mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Passthrough for ssh commands to proxy
This commit is contained in:
parent
6172129f6f
commit
e26cb1aca4
@ -187,6 +187,7 @@ dist_tmate_slave_SOURCES = \
|
||||
tmate-slave.c \
|
||||
tmate-ssh-client-pty.c \
|
||||
tmate-ssh-daemon.c \
|
||||
tmate-ssh-exec.c \
|
||||
tmate-ssh-server.c \
|
||||
tmux-bare.c \
|
||||
tty-acs.c \
|
||||
|
1
client.c
1
client.c
@ -329,6 +329,7 @@ client_send_identify(int flags)
|
||||
sizeof(data.ip_address));
|
||||
strncpy(data.pubkey, tmate_session->ssh_client.pubkey,
|
||||
sizeof(data.pubkey));
|
||||
data.readonly = tmate_session->readonly;
|
||||
#endif
|
||||
|
||||
data.flags = flags;
|
||||
|
@ -1033,6 +1033,7 @@ server_client_msg_identify(
|
||||
#ifdef TMATE_SLAVE
|
||||
c->ip_address = xstrdup(data->ip_address);
|
||||
c->pubkey = xstrdup(data->pubkey);
|
||||
c->readonly = data->readonly;
|
||||
tmate_notify_client_join(tmate_session, c);
|
||||
#endif
|
||||
}
|
||||
|
@ -40,6 +40,14 @@ void msgpack_pack_string(msgpack_packer *pk, const char *str)
|
||||
}
|
||||
}
|
||||
|
||||
void msgpack_pack_boolean(msgpack_packer *pk, bool value)
|
||||
{
|
||||
if (value)
|
||||
msgpack_pack_true(pk);
|
||||
else
|
||||
msgpack_pack_false(pk);
|
||||
}
|
||||
|
||||
/* Copy/pasted from msgpack sources, except we include the v4 support */
|
||||
int _msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
|
||||
{
|
||||
@ -195,6 +203,24 @@ int64_t unpack_int(struct tmate_unpacker *uk)
|
||||
return val;
|
||||
}
|
||||
|
||||
bool unpack_bool(struct tmate_unpacker *uk)
|
||||
{
|
||||
bool val;
|
||||
|
||||
if (uk->argc == 0)
|
||||
tmate_decoder_error();
|
||||
|
||||
if (uk->argv[0].type != MSGPACK_OBJECT_BOOLEAN)
|
||||
tmate_decoder_error();
|
||||
|
||||
val = uk->argv[0].via.boolean;
|
||||
|
||||
uk->argv++;
|
||||
uk->argc--;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void unpack_buffer(struct tmate_unpacker *uk, const char **buf, size_t *len)
|
||||
{
|
||||
if (uk->argc == 0)
|
||||
|
@ -10,6 +10,7 @@ enum tmate_control_out_msg_types {
|
||||
TMATE_CTL_SNAPSHOT,
|
||||
TMATE_CTL_CLIENT_JOIN,
|
||||
TMATE_CTL_CLIENT_LEFT,
|
||||
TMATE_CTL_EXEC,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -18,8 +19,9 @@ enum tmate_control_out_msg_types {
|
||||
[TMATE_CTL_DEAMON_OUT_MSG, object: msg]
|
||||
[TMATE_CTL_SNAPSHOT, [[int: pane_id, [int: cur_x, int: cur_y], int: mode,
|
||||
[[string: line_utf8, [int: char_attr, ...]], ...], ...], ...]]
|
||||
[TMATE_CTL_CLIENT_JOIN, int: client_id, string: ip_address, string: pubkey]
|
||||
[TMATE_CTL_CLIENT_JOIN, int: client_id, string: ip_address, string: pubkey, boolean: readonly]
|
||||
[TMATE_CTL_CLIENT_LEFT, int: client_id]
|
||||
[TMATE_CTL_EXEC, string: username, string: ip_address, string: pubkey, string: command]
|
||||
*/
|
||||
|
||||
enum tmate_control_in_msg_types {
|
||||
@ -27,6 +29,7 @@ enum tmate_control_in_msg_types {
|
||||
TMATE_CTL_REQUEST_SNAPSHOT,
|
||||
TMATE_CTL_PANE_KEYS,
|
||||
TMATE_CTL_RESIZE,
|
||||
TMATE_CTL_EXEC_RESPONSE,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -34,6 +37,7 @@ enum tmate_control_in_msg_types {
|
||||
[TMATE_CTL_REQUEST_SNAPSHOT, int: max_history_lines]
|
||||
[TMATE_CTL_PANE_KEYS, int: pane_id, string: keys]
|
||||
[TMATE_CTL_RESIZE, int: sx, int: sy] // sx == -1: no clients
|
||||
[TMATE_CTL_EXEC_RESPONSE, int: exit_code, string: message]
|
||||
*/
|
||||
|
||||
enum tmate_daemon_out_msg_types {
|
||||
|
111
tmate-proxy.c
111
tmate-proxy.c
@ -1,6 +1,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tmate.h"
|
||||
#include "tmate-protocol.h"
|
||||
@ -147,7 +148,20 @@ static void ctl_resize(struct tmate_session *session,
|
||||
recalculate_sizes();
|
||||
}
|
||||
|
||||
void tmate_dispatch_proxy_message(struct tmate_session *session,
|
||||
static void ctl_ssh_exec_response(struct tmate_session *session,
|
||||
struct tmate_unpacker *uk)
|
||||
{
|
||||
int exit_code;
|
||||
char *message;
|
||||
|
||||
exit_code = unpack_int(uk);
|
||||
message = unpack_string(uk);
|
||||
|
||||
tmate_dump_exec_response(session, exit_code, message);
|
||||
free(message);
|
||||
}
|
||||
|
||||
static void tmate_dispatch_proxy_message(struct tmate_session *session,
|
||||
struct tmate_unpacker *uk)
|
||||
{
|
||||
int cmd = unpack_int(uk);
|
||||
@ -157,21 +171,38 @@ void tmate_dispatch_proxy_message(struct tmate_session *session,
|
||||
dispatch(TMATE_CTL_REQUEST_SNAPSHOT, ctl_daemon_request_snapshot);
|
||||
dispatch(TMATE_CTL_PANE_KEYS, ctl_pane_keys);
|
||||
dispatch(TMATE_CTL_RESIZE, ctl_resize);
|
||||
dispatch(TMATE_CTL_EXEC_RESPONSE, ctl_ssh_exec_response);
|
||||
default: tmate_warn("Bad proxy message type: %d", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void tmate_proxy_exec(struct tmate_session *session, const char *command)
|
||||
{
|
||||
struct tmate_ssh_client *client = &session->ssh_client;
|
||||
|
||||
if (!tmate_has_proxy())
|
||||
return;
|
||||
|
||||
pack(array, 5);
|
||||
pack(int, TMATE_CTL_EXEC);
|
||||
pack(string, client->username);
|
||||
pack(string, client->ip_address);
|
||||
pack(string, client->pubkey);
|
||||
pack(string, command);
|
||||
}
|
||||
|
||||
void tmate_notify_client_join(struct tmate_session *session,
|
||||
struct client *c)
|
||||
{
|
||||
if (!tmate_has_proxy())
|
||||
return;
|
||||
|
||||
pack(array, 4);
|
||||
pack(array, 5);
|
||||
pack(int, TMATE_CTL_CLIENT_JOIN);
|
||||
pack(int, c->id);
|
||||
pack(string, c->ip_address);
|
||||
pack(string, c->pubkey);
|
||||
pack(boolean, c->readonly);
|
||||
}
|
||||
|
||||
void tmate_notify_client_left(struct tmate_session *session,
|
||||
@ -216,13 +247,87 @@ void tmate_send_proxy_header(struct tmate_session *session)
|
||||
pack(string, session->session_token_ro);
|
||||
}
|
||||
|
||||
void tmate_init_proxy_session(struct tmate_session *session)
|
||||
static void on_proxy_decoder_read(void *userdata, struct tmate_unpacker *uk)
|
||||
{
|
||||
struct tmate_session *session = userdata;
|
||||
tmate_dispatch_proxy_message(session, uk);
|
||||
}
|
||||
|
||||
static void on_proxy_read(struct bufferevent *bev, void *_session)
|
||||
{
|
||||
struct tmate_session *session = _session;
|
||||
struct evbuffer *proxy_in;
|
||||
ssize_t written;
|
||||
char *buf;
|
||||
size_t len;
|
||||
|
||||
proxy_in = bufferevent_get_input(session->bev_proxy);
|
||||
|
||||
while (evbuffer_get_length(proxy_in)) {
|
||||
tmate_decoder_get_buffer(&session->proxy_decoder, &buf, &len);
|
||||
|
||||
if (len == 0)
|
||||
tmate_fatal("No more room in client decoder. Message too big?");
|
||||
|
||||
written = evbuffer_remove(proxy_in, buf, len);
|
||||
if (written < 0)
|
||||
tmate_fatal("Cannot read proxy buffer");
|
||||
|
||||
tmate_decoder_commit(&session->proxy_decoder, written);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_proxy_encoder_write(void *userdata, struct evbuffer *buffer)
|
||||
{
|
||||
struct tmate_session *session = userdata;
|
||||
struct evbuffer *proxy_out;
|
||||
size_t len;
|
||||
|
||||
proxy_out = bufferevent_get_output(session->bev_proxy);
|
||||
|
||||
if (evbuffer_add_buffer(proxy_out, buffer) < 0)
|
||||
tmate_fatal("Cannot write to proxy buffer");
|
||||
}
|
||||
|
||||
static void on_proxy_event_default(struct tmate_session *session, short events)
|
||||
{
|
||||
if (events & BEV_EVENT_EOF)
|
||||
tmate_fatal("Connection to proxy closed");
|
||||
|
||||
if (events & BEV_EVENT_ERROR)
|
||||
tmate_fatal("Connection to proxy error: %s",
|
||||
evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
|
||||
}
|
||||
|
||||
static void on_proxy_event(struct bufferevent *bev, short events, void *_session)
|
||||
{
|
||||
struct tmate_session *session = _session;
|
||||
session->on_proxy_error(session, events);
|
||||
}
|
||||
|
||||
void tmate_init_proxy(struct tmate_session *session,
|
||||
on_proxy_error_cb on_proxy_error)
|
||||
{
|
||||
if (!tmate_has_proxy())
|
||||
return;
|
||||
|
||||
session->proxy_sx = -1;
|
||||
session->proxy_sy = -1;
|
||||
|
||||
/* session->proxy_fd is already connected */
|
||||
session->bev_proxy = bufferevent_socket_new(ev_base, session->proxy_fd,
|
||||
BEV_OPT_CLOSE_ON_FREE);
|
||||
if (!session->bev_proxy)
|
||||
tmate_fatal("Cannot setup socket bufferevent");
|
||||
|
||||
session->on_proxy_error = on_proxy_error ?: on_proxy_event_default;
|
||||
|
||||
bufferevent_setcb(session->bev_proxy,
|
||||
on_proxy_read, NULL, on_proxy_event, session);
|
||||
bufferevent_enable(session->bev_proxy, EV_READ | EV_WRITE);
|
||||
|
||||
tmate_encoder_init(&session->proxy_encoder, on_proxy_encoder_write, session);
|
||||
tmate_decoder_init(&session->proxy_decoder, on_proxy_decoder_read, session);
|
||||
}
|
||||
|
||||
static int _tmate_connect_to_proxy(const char *hostname, int port)
|
||||
|
@ -434,10 +434,26 @@ static void tmate_spawn_slave_pty_client(struct tmate_session *session)
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
static void tmate_spawn_slave_exec(struct tmate_session *session)
|
||||
{
|
||||
close_fds_except((int[]){ssh_get_fd(session->ssh_client.session),
|
||||
log_file ? fileno(log_file) : -1,
|
||||
session->proxy_fd}, 3);
|
||||
jail();
|
||||
event_reinit(ev_base);
|
||||
|
||||
tmate_client_exec_init(session);
|
||||
|
||||
if (event_base_dispatch(ev_base) < 0)
|
||||
tmate_fatal("Cannot run event loop");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void tmate_spawn_slave(struct tmate_session *session)
|
||||
{
|
||||
switch (session->ssh_client.role) {
|
||||
case TMATE_ROLE_DAEMON: tmate_spawn_slave_daemon(session); break;
|
||||
case TMATE_ROLE_PTY_CLIENT: tmate_spawn_slave_pty_client(session); break;
|
||||
case TMATE_ROLE_EXEC: tmate_spawn_slave_exec(session); break;
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +1,6 @@
|
||||
#include "tmate.h"
|
||||
#include <errno.h>
|
||||
|
||||
static void on_proxy_decoder_read(void *userdata, struct tmate_unpacker *uk)
|
||||
{
|
||||
struct tmate_session *session = userdata;
|
||||
tmate_dispatch_proxy_message(session, uk);
|
||||
}
|
||||
|
||||
static void on_proxy_read(struct bufferevent *bev, void *_session)
|
||||
{
|
||||
struct tmate_session *session = _session;
|
||||
struct evbuffer *proxy_in;
|
||||
ssize_t written;
|
||||
char *buf;
|
||||
size_t len;
|
||||
|
||||
proxy_in = bufferevent_get_input(session->bev_proxy);
|
||||
|
||||
while (evbuffer_get_length(proxy_in)) {
|
||||
tmate_decoder_get_buffer(&session->proxy_decoder, &buf, &len);
|
||||
|
||||
if (len == 0)
|
||||
tmate_fatal("No more room in client decoder. Message too big?");
|
||||
|
||||
written = evbuffer_remove(proxy_in, buf, len);
|
||||
if (written < 0)
|
||||
tmate_fatal("Cannot read proxy buffer");
|
||||
|
||||
tmate_decoder_commit(&session->proxy_decoder, written);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_proxy_encoder_write(void *userdata, struct evbuffer *buffer)
|
||||
{
|
||||
struct tmate_session *session = userdata;
|
||||
struct evbuffer *proxy_out;
|
||||
size_t len;
|
||||
|
||||
proxy_out = bufferevent_get_output(session->bev_proxy);
|
||||
|
||||
if (evbuffer_add_buffer(proxy_out, buffer) < 0)
|
||||
tmate_fatal("Cannot write to proxy buffer");
|
||||
}
|
||||
|
||||
static void on_proxy_event(struct bufferevent *bev, short events, void *_session)
|
||||
{
|
||||
if (events & BEV_EVENT_EOF)
|
||||
tmate_fatal("Connection to proxy closed");
|
||||
|
||||
if (events & BEV_EVENT_ERROR)
|
||||
tmate_fatal("Connection to proxy error: %s",
|
||||
evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
|
||||
}
|
||||
|
||||
static void on_daemon_decoder_read(void *userdata, struct tmate_unpacker *uk)
|
||||
{
|
||||
struct tmate_session *session = userdata;
|
||||
@ -117,25 +65,6 @@ static void on_daemon_encoder_write(void *userdata, struct evbuffer *buffer)
|
||||
}
|
||||
}
|
||||
|
||||
static void init_proxy(struct tmate_session *session)
|
||||
{
|
||||
/* session->proxy_fd is already connected */
|
||||
session->bev_proxy = bufferevent_socket_new(ev_base, session->proxy_fd,
|
||||
BEV_OPT_CLOSE_ON_FREE);
|
||||
if (!session->bev_proxy)
|
||||
tmate_fatal("Cannot setup socket bufferevent");
|
||||
|
||||
bufferevent_setcb(session->bev_proxy,
|
||||
on_proxy_read, NULL, on_proxy_event, session);
|
||||
bufferevent_enable(session->bev_proxy, EV_READ | EV_WRITE);
|
||||
|
||||
tmate_encoder_init(&session->proxy_encoder, on_proxy_encoder_write, session);
|
||||
tmate_decoder_init(&session->proxy_decoder, on_proxy_decoder_read, session);
|
||||
|
||||
tmate_init_proxy_session(session);
|
||||
tmate_send_proxy_header(session);
|
||||
}
|
||||
|
||||
void tmate_daemon_init(struct tmate_session *session)
|
||||
{
|
||||
struct tmate_ssh_client *client = &session->ssh_client;
|
||||
@ -149,6 +78,6 @@ void tmate_daemon_init(struct tmate_session *session)
|
||||
tmate_encoder_init(&session->daemon_encoder, on_daemon_encoder_write, session);
|
||||
tmate_decoder_init(&session->daemon_decoder, on_daemon_decoder_read, session);
|
||||
|
||||
if (tmate_has_proxy())
|
||||
init_proxy(session);
|
||||
tmate_init_proxy(session, NULL);
|
||||
tmate_send_proxy_header(session);
|
||||
}
|
||||
|
37
tmate-ssh-exec.c
Normal file
37
tmate-ssh-exec.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "tmate.h"
|
||||
#include <errno.h>
|
||||
#include <libssh/server.h>
|
||||
|
||||
void tmate_dump_exec_response(struct tmate_session *session,
|
||||
int exit_code, const char *message)
|
||||
{
|
||||
struct tmate_ssh_client *client = &session->ssh_client;
|
||||
|
||||
ssh_channel_write(client->channel, message, strlen(message));
|
||||
ssh_channel_request_send_exit_status(client->channel, exit_code);
|
||||
|
||||
ssh_channel_send_eof(client->channel);
|
||||
ssh_channel_close(client->channel);
|
||||
|
||||
if (event_base_loopexit(ev_base, NULL) < 0)
|
||||
tmate_fatal("cannot stop event loop");
|
||||
}
|
||||
|
||||
static void on_proxy_error(struct tmate_session *session, short events)
|
||||
{
|
||||
tmate_warn("Lost proxy connection");
|
||||
tmate_dump_exec_response(session, 1, "Internal Error\r\n");
|
||||
}
|
||||
|
||||
void tmate_client_exec_init(struct tmate_session *session)
|
||||
{
|
||||
struct tmate_ssh_client *client = &session->ssh_client;
|
||||
|
||||
memset(&client->channel_cb, 0, sizeof(client->channel_cb));
|
||||
ssh_callbacks_init(&client->channel_cb);
|
||||
ssh_set_channel_callbacks(client->channel, &client->channel_cb);
|
||||
|
||||
tmate_init_proxy(session, on_proxy_error);
|
||||
|
||||
tmate_proxy_exec(session, client->exec_command);
|
||||
}
|
@ -45,6 +45,9 @@ static int shell_request(ssh_session session, ssh_channel channel,
|
||||
{
|
||||
struct tmate_ssh_client *client = userdata;
|
||||
|
||||
if (client->role)
|
||||
return 1;
|
||||
|
||||
client->role = TMATE_ROLE_PTY_CLIENT;
|
||||
|
||||
return 0;
|
||||
@ -55,12 +58,32 @@ static int subsystem_request(ssh_session session, ssh_channel channel,
|
||||
{
|
||||
struct tmate_ssh_client *client = userdata;
|
||||
|
||||
if (client->role)
|
||||
return 1;
|
||||
|
||||
if (!strcmp(subsystem, "tmate"))
|
||||
client->role = TMATE_ROLE_DAEMON;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exec_request(ssh_session session, ssh_channel channel,
|
||||
const char *command, void *userdata)
|
||||
{
|
||||
struct tmate_ssh_client *client = userdata;
|
||||
|
||||
if (client->role)
|
||||
return 1;
|
||||
|
||||
if (!tmate_has_proxy())
|
||||
return 1;
|
||||
|
||||
client->role = TMATE_ROLE_EXEC;
|
||||
client->exec_command = xstrdup(command);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssh_channel channel_open_request_cb(ssh_session session, void *userdata)
|
||||
{
|
||||
struct tmate_ssh_client *client = userdata;
|
||||
@ -82,9 +105,10 @@ static ssh_channel channel_open_request_cb(ssh_session session, void *userdata)
|
||||
memset(&client->channel_cb, 0, sizeof(client->channel_cb));
|
||||
ssh_callbacks_init(&client->channel_cb);
|
||||
client->channel_cb.userdata = client;
|
||||
client->channel_cb.channel_pty_request_function = pty_request,
|
||||
client->channel_cb.channel_shell_request_function = shell_request,
|
||||
client->channel_cb.channel_subsystem_request_function = subsystem_request,
|
||||
client->channel_cb.channel_pty_request_function = pty_request;
|
||||
client->channel_cb.channel_shell_request_function = shell_request;
|
||||
client->channel_cb.channel_subsystem_request_function = subsystem_request;
|
||||
client->channel_cb.channel_exec_request_function = exec_request;
|
||||
ssh_set_channel_callbacks(client->channel, &client->channel_cb);
|
||||
|
||||
return client->channel;
|
||||
|
35
tmate.h
35
tmate.h
@ -46,6 +46,7 @@ extern void tmate_encoder_init(struct tmate_encoder *encoder,
|
||||
|
||||
/* These functions deal with dual v4/v5 support through mpac_version */
|
||||
extern void msgpack_pack_string(msgpack_packer *pk, const char *str);
|
||||
extern void msgpack_pack_boolean(msgpack_packer *pk, bool value);
|
||||
extern int _msgpack_pack_object(msgpack_packer *pk, msgpack_object d);
|
||||
#define msgpack_pack_object _msgpack_pack_object
|
||||
|
||||
@ -73,6 +74,7 @@ struct tmate_unpacker {
|
||||
extern void init_unpacker(struct tmate_unpacker *uk, msgpack_object obj);
|
||||
extern void tmate_decoder_error(void);
|
||||
extern int64_t unpack_int(struct tmate_unpacker *uk);
|
||||
extern bool unpack_bool(struct tmate_unpacker *uk);
|
||||
extern void unpack_buffer(struct tmate_unpacker *uk, const char **buf, size_t *len);
|
||||
extern char *unpack_string(struct tmate_unpacker *uk);
|
||||
extern void unpack_array(struct tmate_unpacker *uk, struct tmate_unpacker *nested);
|
||||
@ -88,8 +90,6 @@ extern void unpack_array(struct tmate_unpacker *uk, struct tmate_unpacker *neste
|
||||
|
||||
extern void printflike1 tmate_notify(const char *fmt, ...);
|
||||
extern void printflike2 tmate_notify_later(int timeout, const char *fmt, ...);
|
||||
extern void tmate_notify_client_join(struct tmate_session *s, struct client *c);
|
||||
extern void tmate_notify_client_left(struct tmate_session *s, struct client *c);
|
||||
|
||||
extern void tmate_client_resize(u_int sx, u_int sy);
|
||||
extern void tmate_client_pane_key(int pane_id, int key);
|
||||
@ -109,13 +109,19 @@ extern char *tmate_left_status, *tmate_right_status;
|
||||
extern void tmate_dispatch_daemon_message(struct tmate_session *session,
|
||||
struct tmate_unpacker *uk);
|
||||
|
||||
/* tmate-ssh-client.c */
|
||||
/* tmate-ssh-daemon.c */
|
||||
|
||||
#define TMATE_KEYFRAME_INTERVAL_SEC 10
|
||||
#define TMATE_KEYFRAME_MAX_SIZE 1024*1024
|
||||
|
||||
extern void tmate_daemon_init(struct tmate_session *session);
|
||||
|
||||
/* tmate-ssh-exec.c */
|
||||
|
||||
extern void tmate_dump_exec_response(struct tmate_session *session,
|
||||
int exit_code, const char *message);
|
||||
extern void tmate_client_exec_init(struct tmate_session *session);
|
||||
|
||||
/* tmate-ssh-client-pty.c */
|
||||
|
||||
extern void tmate_client_pty_init(struct tmate_session *session);
|
||||
@ -128,6 +134,7 @@ extern void tmate_flush_pty(struct tmate_session *session);
|
||||
|
||||
#define TMATE_ROLE_DAEMON 1
|
||||
#define TMATE_ROLE_PTY_CLIENT 2
|
||||
#define TMATE_ROLE_EXEC 3
|
||||
|
||||
struct tmate_ssh_client {
|
||||
char ip_address[64];
|
||||
@ -145,6 +152,8 @@ struct tmate_ssh_client {
|
||||
char *username;
|
||||
char *pubkey;
|
||||
|
||||
char *exec_command;
|
||||
|
||||
struct winsize winsize_pty;
|
||||
|
||||
struct event ev_ssh;
|
||||
@ -183,11 +192,13 @@ struct tmate_settings {
|
||||
};
|
||||
extern struct tmate_settings *tmate_settings;
|
||||
|
||||
typedef void on_proxy_error_cb(struct tmate_session *session, short events);
|
||||
|
||||
struct tmate_session {
|
||||
struct tmate_ssh_client ssh_client;
|
||||
int tmux_socket_fd;
|
||||
|
||||
/* only for deamon */
|
||||
/* only for role deamon */
|
||||
const char *session_token;
|
||||
const char *session_token_ro;
|
||||
|
||||
@ -201,11 +212,17 @@ struct tmate_session {
|
||||
struct tmate_encoder proxy_encoder;
|
||||
struct tmate_decoder proxy_decoder;
|
||||
u_int proxy_sx, proxy_sy;
|
||||
on_proxy_error_cb *on_proxy_error;
|
||||
|
||||
/* only for client-pty */
|
||||
/* only for role client-pty */
|
||||
int pty;
|
||||
struct event ev_pty;
|
||||
bool readonly;
|
||||
|
||||
/* only for role-exec */
|
||||
bool response_received;
|
||||
bool response_status;
|
||||
const char *response_message;
|
||||
};
|
||||
|
||||
extern struct tmate_session *tmate_session;
|
||||
@ -216,13 +233,15 @@ extern void tmate_spawn_slave(struct tmate_session *session);
|
||||
|
||||
/* tmate-proxy.c */
|
||||
|
||||
extern void tmate_dispatch_proxy_message(struct tmate_session *session,
|
||||
struct tmate_unpacker *uk);
|
||||
extern void tmate_proxy_exec(struct tmate_session *session, const char *command);
|
||||
extern void tmate_notify_client_join(struct tmate_session *s, struct client *c);
|
||||
extern void tmate_notify_client_left(struct tmate_session *s, struct client *c);
|
||||
|
||||
extern void tmate_send_proxy_daemon_msg(struct tmate_session *session,
|
||||
struct tmate_unpacker *uk);
|
||||
extern void tmate_send_proxy_header(struct tmate_session *session);
|
||||
extern void tmate_init_proxy_session(struct tmate_session *session);
|
||||
extern void tmate_init_proxy(struct tmate_session *session,
|
||||
on_proxy_error_cb on_proxy_error);
|
||||
|
||||
extern int tmate_connect_to_proxy(void);
|
||||
static inline bool tmate_has_proxy(void)
|
||||
|
2
tmux.h
2
tmux.h
@ -480,6 +480,7 @@ struct msg_identify_data {
|
||||
#ifdef TMATE_SLAVE
|
||||
char ip_address[64];
|
||||
char pubkey[2048]; /* hopefully enough :) */
|
||||
int readonly;
|
||||
#endif
|
||||
|
||||
#define IDENTIFY_UTF8 0x1
|
||||
@ -1389,6 +1390,7 @@ struct client {
|
||||
#ifdef TMATE_SLAVE
|
||||
char *ip_address;
|
||||
char *pubkey;
|
||||
int readonly;
|
||||
#endif
|
||||
};
|
||||
ARRAY_DECL(clients, struct client *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user