1
0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2020-11-18 19:53:51 -08:00

Rename proxy -> websocket

This commit is contained in:
Nicolas Viennot 2019-08-24 15:08:03 -04:00
parent 4b20aaf66e
commit 004fe379f6
10 changed files with 116 additions and 111 deletions

View File

@ -184,7 +184,7 @@ dist_tmate_ssh_server_SOURCES = \
tmate-daemon-encoder.c \
tmate-daemon-legacy.c \
tmate-msgpack.c \
tmate-proxy.c \
tmate-websocket.c \
tmate-main.c \
tmate-ssh-client-pty.c \
tmate-ssh-daemon.c \

View File

@ -1,7 +1,7 @@
#!/bin/sh
set -e
if [ "${USE_PROXY}" == "1" ]; then
if [ "${HAS_WEBSOCKET}" == "1" ]; then
set -- -x localhost "$@"
fi

View File

@ -79,11 +79,11 @@ recalculate_sizes(void)
}
#ifdef TMATE_SLAVE
if (tmate_has_proxy()) {
if (tmate_session->proxy_sy < ssy)
ssy = tmate_session->proxy_sy;
if (tmate_session->proxy_sx < ssx)
ssx = tmate_session->proxy_sx;
if (tmate_has_websocket()) {
if (tmate_session->websocket_sy < ssy)
ssy = tmate_session->websocket_sy;
if (tmate_session->websocket_sx < ssx)
ssx = tmate_session->websocket_sx;
}
tmate_client_resize(ssx, ssy);

View File

@ -26,9 +26,9 @@ static void tmate_header(struct tmate_session *session,
tmate_notice("Daemon header: client version: %s, protocol version: %d",
session->client_version, session->client_protocol_version);
if (tmate_has_proxy()) {
/* If we have a proxy, it takes care of all the following notificatons */
tmate_send_proxy_header(session);
if (tmate_has_websocket()) {
/* If we have a websocket, it takes care of all the following notificatons */
tmate_send_websocket_header(session);
return;
}
@ -52,7 +52,7 @@ static void tmate_header(struct tmate_session *session,
static void tmate_ready(__unused struct tmate_session *session,
__unused struct tmate_unpacker *uk)
{
/* used by the proxy */
/* used by the websocket */
}
@ -414,8 +414,8 @@ static void tmate_fin(__unused struct tmate_session *session,
static void tmate_reconnect(__unused struct tmate_session *session,
__unused struct tmate_unpacker *uk)
{
if (!tmate_has_proxy())
tmate_fatal("Cannot do reconnections without the proxy");
if (!tmate_has_websocket())
tmate_fatal("Cannot do reconnections without the websocket server");
}
static void restore_snapshot_grid(struct grid *grid, struct tmate_unpacker *uk)

View File

@ -36,9 +36,9 @@ struct tmate_settings _tmate_settings = {
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
.authorized_keys_path = NULL,
.ssh_port = TMATE_SSH_DEFAULT_PORT,
.proxy_hostname = NULL,
.websocket_hostname = NULL,
.bind_addr = NULL,
.proxy_port = TMATE_DEFAULT_PROXY_PORT,
.websocket_port = TMATE_DEFAULT_WEBSOCKET_PORT,
.tmate_host = NULL,
.log_level = LOG_NOTICE,
.use_syslog = false,
@ -103,7 +103,7 @@ void request_server_termination(void)
static void usage(void)
{
fprintf(stderr, "usage: tmate-ssh-server [-b ip] [-h hostname] [-k keys_dir] [-a authorized_keys_path] [-p port] [-x proxy_hostname] [-q proxy_port] [-s] [-v]\n");
fprintf(stderr, "usage: tmate-ssh-server [-b ip] [-h hostname] [-k keys_dir] [-a authorized_keys_path] [-p port] [-x websocket_hostname] [-q websocket_port] [-s] [-v]\n");
}
static char* get_full_hostname(void)
@ -174,10 +174,10 @@ int main(int argc, char **argv, char **envp)
tmate_settings->ssh_port = atoi(optarg);
break;
case 'x':
tmate_settings->proxy_hostname = xstrdup(optarg);
tmate_settings->websocket_hostname = xstrdup(optarg);
break;
case 'q':
tmate_settings->proxy_port = atoi(optarg);
tmate_settings->websocket_port = atoi(optarg);
break;
case 's':
tmate_settings->use_syslog = true;
@ -212,7 +212,7 @@ int main(int argc, char **argv, char **envp)
(mkdir(TMATE_WORKDIR "/jail", 0700) < 0 && errno != EEXIST))
tmate_fatal("Cannot prepare session in " TMATE_WORKDIR);
/* The proxy needs to access the /session dir to rename sockets */
/* The websocket server needs to access the /session dir to rename sockets */
if ((chmod(TMATE_WORKDIR, 0701) < 0) ||
(chmod(TMATE_WORKDIR "/sessions", 0703) < 0) ||
(chmod(TMATE_WORKDIR "/jail", 0700) < 0))
@ -449,7 +449,7 @@ static void tmate_spawn_daemon(struct tmate_session *session)
close_fds_except((int[]){session->tmux_socket_fd,
ssh_get_fd(session->ssh_client.session),
log_file ? fileno(log_file) : -1,
session->proxy_fd}, 4);
session->websocket_fd}, 4);
jail();
event_reinit(session->ev_base);
@ -516,7 +516,7 @@ static void tmate_spawn_pty_client(struct tmate_session *session)
tmate_client_pty_init(session);
/* the unused session->proxy_fd will get closed automatically */
/* the unused session->websocket_fd will get closed automatically */
close_fds_except((int[]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
session->tmux_socket_fd,
@ -535,7 +535,7 @@ static void tmate_spawn_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);
session->websocket_fd}, 3);
jail();
event_reinit(session->ev_base);

View File

@ -11,7 +11,7 @@ static void on_daemon_decoder_read(void *userdata, struct tmate_unpacker *uk)
{
struct tmate_session *session = userdata;
tmate_send_proxy_daemon_msg(session, uk);
tmate_send_websocket_daemon_msg(session, uk);
tmate_dispatch_daemon_message(session, uk);
}
@ -85,7 +85,7 @@ 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);
tmate_init_proxy(session, NULL);
tmate_init_websocket(session, NULL);
tmate_add_ssh_latency_callback(client, on_latency_callback, session);
}

View File

@ -17,9 +17,9 @@ void tmate_dump_exec_response(struct tmate_session *session,
tmate_fatal("cannot stop event loop");
}
static void on_proxy_error(struct tmate_session *session, __unused short events)
static void on_websocket_error(struct tmate_session *session, __unused short events)
{
tmate_warn("Lost proxy connection");
tmate_warn("Lost websocket server connection");
tmate_dump_exec_response(session, 1, "Internal Error\r\n");
}
@ -31,7 +31,7 @@ void tmate_client_exec_init(struct tmate_session *session)
ssh_callbacks_init(&client->channel_cb);
ssh_set_channel_callbacks(client->channel, &client->channel_cb);
tmate_init_proxy(session, on_proxy_error);
tmate_init_websocket(session, on_websocket_error);
tmate_proxy_exec(session, client->exec_command);
tmate_websocket_exec(session, client->exec_command);
}

View File

@ -67,7 +67,7 @@ static int exec_request(__unused ssh_session session,
if (client->role)
return 1;
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return 1;
client->role = TMATE_ROLE_EXEC;
@ -242,12 +242,12 @@ static void client_bootstrap(struct tmate_session *_session)
alarm(grace_period);
/*
* We should die early if we can't connect to proxy. This way the
* tmate daemon will pick another server to work on.
* We should die early if we can't connect to websocket server. This
* way the tmate daemon will pick another server to work on.
*/
_session->proxy_fd = -1;
if (tmate_has_proxy())
_session->proxy_fd = tmate_connect_to_proxy();
_session->websocket_fd = -1;
if (tmate_has_websocket())
_session->websocket_fd = tmate_connect_to_websocket();
ssh_server_cb.userdata = client;
ssh_callbacks_init(&ssh_server_cb);

View File

@ -9,9 +9,14 @@
#include "tmate.h"
#include "tmate-protocol.h"
/*
* The websocket refers to the websocket server.
* (https://github.com/tmate-io/tmate-websocket)
*/
#define CONTROL_PROTOCOL_VERSION 2
#define pack(what, ...) _pack(&tmate_session->proxy_encoder, what, __VA_ARGS__)
#define pack(what, ...) _pack(&tmate_session->websocket_encoder, what, __VA_ARGS__)
static void ctl_daemon_fwd_msg(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
@ -143,8 +148,8 @@ static void ctl_pane_keys(__unused struct tmate_session *session,
static void ctl_resize(struct tmate_session *session,
struct tmate_unpacker *uk)
{
session->proxy_sx = (u_int)unpack_int(uk);
session->proxy_sy = (u_int)unpack_int(uk);
session->websocket_sx = (u_int)unpack_int(uk);
session->websocket_sy = (u_int)unpack_int(uk);
recalculate_sizes();
}
@ -173,7 +178,7 @@ static void ctl_rename_session(struct tmate_session *session,
free(stoken_ro);
}
static void tmate_dispatch_proxy_message(struct tmate_session *session,
static void tmate_dispatch_websocket_message(struct tmate_session *session,
struct tmate_unpacker *uk)
{
int cmd = unpack_int(uk);
@ -185,15 +190,15 @@ static void tmate_dispatch_proxy_message(struct tmate_session *session,
dispatch(TMATE_CTL_RESIZE, ctl_resize);
dispatch(TMATE_CTL_EXEC_RESPONSE, ctl_ssh_exec_response);
dispatch(TMATE_CTL_RENAME_SESSION, ctl_rename_session);
default: tmate_warn("Bad proxy message type: %d", cmd);
default: tmate_warn("Bad websocket server message type: %d", cmd);
}
}
void tmate_proxy_exec(struct tmate_session *session, const char *command)
void tmate_websocket_exec(struct tmate_session *session, const char *command)
{
struct tmate_ssh_client *client = &session->ssh_client;
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
pack(array, 5);
@ -209,7 +214,7 @@ void tmate_notify_client_join(__unused struct tmate_session *session,
{
tmate_notice("Client joined (cid=%d)", c->id);
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
c->flags |= CLIENT_TMATE_NOTIFIED_JOIN;
@ -227,7 +232,7 @@ void tmate_notify_client_left(__unused struct tmate_session *session,
{
tmate_notice("Client left (cid=%d)", c->id);
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
if (!(c->flags & CLIENT_TMATE_NOTIFIED_JOIN))
@ -245,7 +250,7 @@ void tmate_notify_latency(__unused struct tmate_session *session,
{
int cid;
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
cid = c ? c->id : -1;
@ -257,12 +262,12 @@ void tmate_notify_latency(__unused struct tmate_session *session,
pack(int, latency_ms);
}
void tmate_send_proxy_daemon_msg(__unused struct tmate_session *session,
void tmate_send_websocket_daemon_msg(__unused struct tmate_session *session,
struct tmate_unpacker *uk)
{
int i;
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
pack(array, 2);
@ -273,12 +278,12 @@ void tmate_send_proxy_daemon_msg(__unused struct tmate_session *session,
pack(object, uk->argv[i]);
}
void tmate_send_proxy_header(struct tmate_session *session)
void tmate_send_websocket_header(struct tmate_session *session)
{
char port_arg[16] = {0};
char ssh_cmd_fmt[512];
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
pack(array, 9);
@ -298,89 +303,89 @@ void tmate_send_proxy_header(struct tmate_session *session)
pack(int, session->client_protocol_version);
}
static void on_proxy_decoder_read(void *userdata, struct tmate_unpacker *uk)
static void on_websocket_decoder_read(void *userdata, struct tmate_unpacker *uk)
{
struct tmate_session *session = userdata;
tmate_dispatch_proxy_message(session, uk);
tmate_dispatch_websocket_message(session, uk);
}
static void on_proxy_read(__unused struct bufferevent *bev, void *_session)
static void on_websocket_read(__unused struct bufferevent *bev, void *_session)
{
struct tmate_session *session = _session;
struct evbuffer *proxy_in;
struct evbuffer *websocket_in;
ssize_t written;
char *buf;
size_t len;
proxy_in = bufferevent_get_input(session->bev_proxy);
websocket_in = bufferevent_get_input(session->bev_websocket);
while (evbuffer_get_length(proxy_in)) {
tmate_decoder_get_buffer(&session->proxy_decoder, &buf, &len);
while (evbuffer_get_length(websocket_in)) {
tmate_decoder_get_buffer(&session->websocket_decoder, &buf, &len);
if (len == 0)
tmate_fatal("No more room in client decoder. Message too big?");
written = evbuffer_remove(proxy_in, buf, len);
written = evbuffer_remove(websocket_in, buf, len);
if (written < 0)
tmate_fatal("Cannot read proxy buffer");
tmate_fatal("Cannot read websocket buffer");
tmate_decoder_commit(&session->proxy_decoder, written);
tmate_decoder_commit(&session->websocket_decoder, written);
}
}
static void on_proxy_encoder_write(void *userdata, struct evbuffer *buffer)
static void on_websocket_encoder_write(void *userdata, struct evbuffer *buffer)
{
struct tmate_session *session = userdata;
struct evbuffer *proxy_out;
struct evbuffer *websocket_out;
proxy_out = bufferevent_get_output(session->bev_proxy);
websocket_out = bufferevent_get_output(session->bev_websocket);
if (evbuffer_add_buffer(proxy_out, buffer) < 0)
tmate_fatal("Cannot write to proxy buffer");
if (evbuffer_add_buffer(websocket_out, buffer) < 0)
tmate_fatal("Cannot write to websocket buffer");
}
static void on_proxy_event_default(__unused struct tmate_session *session, short events)
static void on_websocket_event_default(__unused struct tmate_session *session, short events)
{
if (events & BEV_EVENT_EOF)
tmate_fatal("Connection to proxy closed");
tmate_fatal("Connection to websocket closed");
if (events & BEV_EVENT_ERROR)
tmate_fatal("Connection to proxy error: %s",
tmate_fatal("Connection to websocket error: %s",
evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()));
}
static void on_proxy_event(__unused struct bufferevent *bev, short events, void *_session)
static void on_websocket_event(__unused struct bufferevent *bev, short events, void *_session)
{
struct tmate_session *session = _session;
session->on_proxy_error(session, events);
session->on_websocket_error(session, events);
}
void tmate_init_proxy(struct tmate_session *session,
on_proxy_error_cb on_proxy_error)
void tmate_init_websocket(struct tmate_session *session,
on_websocket_error_cb on_websocket_error)
{
if (!tmate_has_proxy())
if (!tmate_has_websocket())
return;
session->proxy_sx = -1;
session->proxy_sy = -1;
session->websocket_sx = -1;
session->websocket_sy = -1;
/* session->proxy_fd is already connected */
session->bev_proxy = bufferevent_socket_new(session->ev_base, session->proxy_fd,
/* session->websocket_fd is already connected */
session->bev_websocket = bufferevent_socket_new(session->ev_base, session->websocket_fd,
BEV_OPT_CLOSE_ON_FREE);
if (!session->bev_proxy)
if (!session->bev_websocket)
tmate_fatal("Cannot setup socket bufferevent");
session->on_proxy_error = on_proxy_error ?: on_proxy_event_default;
session->on_websocket_error = on_websocket_error ?: on_websocket_event_default;
bufferevent_setcb(session->bev_proxy,
on_proxy_read, NULL, on_proxy_event, session);
bufferevent_enable(session->bev_proxy, EV_READ | EV_WRITE);
bufferevent_setcb(session->bev_websocket,
on_websocket_read, NULL, on_websocket_event, session);
bufferevent_enable(session->bev_websocket, 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_encoder_init(&session->websocket_encoder, on_websocket_encoder_write, session);
tmate_decoder_init(&session->websocket_decoder, on_websocket_decoder_read, session);
}
static int _tmate_connect_to_proxy(const char *hostname, int port)
static int _tmate_connect_to_websocket(const char *hostname, int port)
{
int sockfd = -1;
struct sockaddr_in servaddr;
@ -400,24 +405,24 @@ static int _tmate_connect_to_proxy(const char *hostname, int port)
servaddr.sin_port = htons(port);
if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
tmate_fatal("Cannot connect to proxy at %s:%d", hostname, port);
tmate_fatal("Cannot connect to websocket at %s:%d", hostname, port);
{
int flag = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) < 0)
tmate_fatal("Can't set proxy socket to TCP_NODELAY");
tmate_fatal("Can't set websocket socket to TCP_NODELAY");
}
if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)
tmate_fatal("Can't set proxy socket to non-blocking");
tmate_fatal("Can't set websocket socket to non-blocking");
tmate_notice("Connected to proxy at %s:%d", hostname, port);
tmate_notice("Connected to websocket at %s:%d", hostname, port);
return sockfd;
}
int tmate_connect_to_proxy(void)
int tmate_connect_to_websocket(void)
{
return _tmate_connect_to_proxy(tmate_settings->proxy_hostname,
tmate_settings->proxy_port);
return _tmate_connect_to_websocket(tmate_settings->websocket_hostname,
tmate_settings->websocket_port);
}

38
tmate.h
View File

@ -201,7 +201,7 @@ extern void tmate_ssh_server_main(struct tmate_session *session,
#define TMATE_SSH_DEFAULT_KEYS_DIR "keys"
#define TMATE_DEFAULT_PROXY_PORT 4002
#define TMATE_DEFAULT_WEBSOCKET_PORT 4002
#define TMATE_TOKEN_LEN 25
#define TMATE_WORKDIR "/tmp/tmate"
@ -211,8 +211,8 @@ struct tmate_settings {
const char *keys_dir;
const char *authorized_keys_path;
int ssh_port;
const char *proxy_hostname;
int proxy_port;
const char *websocket_hostname;
int websocket_port;
const char *tmate_host;
const char *bind_addr;
int log_level;
@ -220,7 +220,7 @@ struct tmate_settings {
};
extern struct tmate_settings *tmate_settings;
typedef void on_proxy_error_cb(struct tmate_session *session, short events);
typedef void on_websocket_error_cb(struct tmate_session *session, short events);
struct tmate_session {
struct event_base *ev_base;
@ -237,12 +237,12 @@ struct tmate_session {
int client_protocol_version;
struct event ev_notify_timer;
int proxy_fd;
struct bufferevent *bev_proxy;
struct tmate_encoder proxy_encoder;
struct tmate_decoder proxy_decoder;
u_int proxy_sx, proxy_sy;
on_proxy_error_cb *on_proxy_error;
int websocket_fd;
struct bufferevent *bev_websocket;
struct tmate_encoder websocket_encoder;
struct tmate_decoder websocket_decoder;
u_int websocket_sx, websocket_sy;
on_websocket_error_cb *on_websocket_error;
/* only for role client-pty */
int pty;
@ -262,23 +262,23 @@ extern void request_server_termination(void);
extern void tmate_spawn(struct tmate_session *session);
extern void set_session_token(struct tmate_session *session, const char *token);
/* tmate-proxy.c */
/* tmate-websocket.c */
extern void tmate_proxy_exec(struct tmate_session *session, const char *command);
extern void tmate_websocket_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_notify_latency(struct tmate_session *session, struct client *c, int latency_ms);
extern void tmate_send_proxy_daemon_msg(struct tmate_session *session,
extern void tmate_send_websocket_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(struct tmate_session *session,
on_proxy_error_cb on_proxy_error);
extern void tmate_send_websocket_header(struct tmate_session *session);
extern void tmate_init_websocket(struct tmate_session *session,
on_websocket_error_cb on_websocket_error);
extern int tmate_connect_to_proxy(void);
static inline bool tmate_has_proxy(void)
extern int tmate_connect_to_websocket(void);
static inline bool tmate_has_websocket(void)
{
return !!tmate_settings->proxy_hostname;
return !!tmate_settings->websocket_hostname;
}
/* tmate-debug.c */