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

client notification through master

This commit is contained in:
Nicolas Viennot 2015-10-05 17:58:53 -07:00
parent 51ba50ac0d
commit 6c62b10e0a
10 changed files with 116 additions and 59 deletions

View File

@ -325,7 +325,10 @@ client_send_identify(int flags)
int fd;
#ifdef TMATE_SLAVE
strcpy(data.ip_address, tmate_session->ssh_client.ip_address);
strncpy(data.ip_address, tmate_session->ssh_client.ip_address,
sizeof(data.ip_address));
strncpy(data.pubkey, tmate_session->ssh_client.pubkey,
sizeof(data.pubkey));
#endif
data.flags = flags;

1
log.c
View File

@ -47,6 +47,7 @@ void
log_event_cb(unused int severity, const char *msg)
{
log_warnx("%s", msg);
sleep(1);
}
void init_logging(const char *program_name, bool use_syslog, int log_level)

View File

@ -78,6 +78,13 @@ recalculate_sizes(void)
}
#ifdef TMATE_SLAVE
if (tmate_has_master()) {
if (tmate_session->master_sy < ssy)
ssy = tmate_session->master_sy;
if (tmate_session->master_sx < ssx)
ssx = tmate_session->master_sx;
}
tmate_client_resize(ssx, ssy);
return;
#endif

View File

@ -111,6 +111,7 @@ server_client_create(int fd)
#ifdef TMATE_SLAVE
c->ip_address = NULL;
c->pubkey = NULL;
#endif
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@ -159,7 +160,7 @@ server_client_lost(struct client *c)
log_debug("lost client %d", c->ibuf.fd);
#ifdef TMATE_SLAVE
tmate_notify_client_left(c);
tmate_notify_client_left(tmate_session, c);
#endif
/*
@ -205,6 +206,8 @@ server_client_lost(struct client *c)
#ifdef TMATE_SLAVE
free(c->ip_address);
c->ip_address = NULL;
free(c->pubkey);
c->pubkey = NULL;
#endif
environ_free(&c->environ);
@ -1029,7 +1032,8 @@ server_client_msg_identify(
#ifdef TMATE_SLAVE
c->ip_address = xstrdup(data->ip_address);
tmate_notify_client_join(c);
c->pubkey = xstrdup(data->pubkey);
tmate_notify_client_join(tmate_session, c);
#endif
}

View File

@ -51,51 +51,6 @@ void printflike2 tmate_notify_later(int timeout, const char *fmt, ...)
evtimer_add(&tmate_session->ev_notify_timer, &tv);
}
static int num_clients(void)
{
unsigned int i, count = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if (ARRAY_ITEM(&clients, i))
count++;
}
return count;
}
static void mate_notify_message(struct client *c, int join)
{
char buf[100];
int count;
static int multi_client;
count = num_clients();
if (count > 1)
multi_client = 1;
if (multi_client)
sprintf(buf, " -- %d mate%s %sconnected",
count,
count == 1 ? " is" : "s are",
(join || !count) ? "" : "still ");
tmate_notify("%s mate has %s the session (%s)%s",
multi_client ? "A" : "Your",
join ? "joined" : "left",
c->ip_address,
multi_client ? buf : "");
}
void tmate_notify_client_join(struct client *c)
{
mate_notify_message(c, 1);
}
void tmate_notify_client_left(struct client *c)
{
mate_notify_message(c, 0);
}
void tmate_send_client_ready(void)
{
if (tmate_session->client_protocol_version < 4)

View File

@ -139,6 +139,14 @@ static void ctl_pane_keys(struct tmate_session *session,
free(str);
}
static void ctl_resize(struct tmate_session *session,
struct tmate_unpacker *uk)
{
session->master_sx = (u_int)unpack_int(uk);
session->master_sy = (u_int)unpack_int(uk);
recalculate_sizes();
}
void tmate_dispatch_master_message(struct tmate_session *session,
struct tmate_unpacker *uk)
{
@ -148,10 +156,35 @@ void tmate_dispatch_master_message(struct tmate_session *session,
dispatch(TMATE_CTL_DEAMON_FWD_MSG, ctl_daemon_fwd_msg);
dispatch(TMATE_CTL_REQUEST_SNAPSHOT, ctl_daemon_request_snapshot);
dispatch(TMATE_CTL_PANE_KEYS, ctl_pane_keys);
default: tmate_fatal("Bad master message type: %d", cmd);
dispatch(TMATE_CTL_RESIZE, ctl_resize);
default: tmate_warn("Bad master message type: %d", cmd);
}
}
void tmate_notify_client_join(struct tmate_session *session,
struct client *c)
{
if (!tmate_has_master())
return;
pack(array, 4);
pack(int, TMATE_CTL_CLIENT_JOIN);
pack(int, c->id);
pack(string, c->ip_address);
pack(string, c->pubkey);
}
void tmate_notify_client_left(struct tmate_session *session,
struct client *c)
{
if (!tmate_has_master())
return;
pack(array, 2);
pack(int, TMATE_CTL_CLIENT_LEFT);
pack(int, c->id);
}
void tmate_send_master_daemon_msg(struct tmate_session *session,
struct tmate_unpacker *uk)
{
@ -188,7 +221,8 @@ void tmate_init_master_session(struct tmate_session *session)
if (!tmate_has_master())
return;
/* Further init */
session->master_sx = -1;
session->master_sy = -1;
}
static int _tmate_connect_to_master(const char *hostname, int port)

View File

@ -10,14 +10,34 @@ enum tmate_control_out_msg_types {
TMATE_CTL_AUTH,
TMATE_CTL_DEAMON_OUT_MSG,
TMATE_CTL_SNAPSHOT,
TMATE_CTL_CLIENT_JOIN,
TMATE_CTL_CLIENT_LEFT,
};
/*
[TMATE_CTL_AUTH, int: ctl_proto_version, string: ip_address, string: pubkey,
string: session_token, string: session_token_ro]
[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_LEFT, int: client_id]
*/
enum tmate_control_in_msg_types {
TMATE_CTL_DEAMON_FWD_MSG,
TMATE_CTL_REQUEST_SNAPSHOT,
TMATE_CTL_PANE_KEYS,
TMATE_CTL_RESIZE,
};
/*
[TMATE_CTL_DEAMON_FWD_MSG, object: msg]
[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
*/
enum tmate_daemon_out_msg_types {
TMATE_OUT_HEADER,
TMATE_OUT_SYNC_LAYOUT,
@ -28,6 +48,23 @@ enum tmate_daemon_out_msg_types {
TMATE_OUT_SYNC_COPY_MODE,
TMATE_OUT_WRITE_COPY_MODE,
};
/*
[TMATE_OUT_HEADER, int: proto_version, string: version]
[TMATE_OUT_SYNC_LAYOUT, [int: sx, int: sy, [[int: win_id, string: win_name,
[[int: pane_id, int: sx, int: sy, int: xoff, int: yoff], ...],
int: active_pane_id], ...], int: active_win_id]
[TMATE_OUT_PTY_DATA, int: pane_id, binary: buffer]
[TMATE_OUT_EXEC_CMD, string: cmd]
[TMATE_OUT_FAILED_CMD, int: client_id, string: cause]
[TMATE_OUT_STATUS, string: left, string: right]
[TMATE_OUT_SYNC_COPY_MODE, int: pane_id, [int: backing, int: oy, int: cx, int: cy,
[int: selx, int: sely, int: flags],
[int: type, string: input_prompt, string: input_str]])
// Any of the array can be []
[TMATE_OUT_WRITE_COPY_MODE, int: pane_id, string: str]
*/
enum tmate_daemon_in_msg_types {
TMATE_IN_NOTIFY,
TMATE_IN_PANE_KEY,
@ -37,4 +74,13 @@ enum tmate_daemon_in_msg_types {
TMATE_IN_READY,
};
/*
[TMATE_IN_NOTIFY, string: msg]
[TMATE_IN_PANE_KEY, int: key]
[TMATE_IN_RESIZE, int: sx, int: sy] // sx == -1: no clients
[TMATE_IN_EXEC_CMD, int: client_id, string: cmd]
[TMATE_IN_SET_ENV, string: name, string: value]
[TMATE_IN_READY]
*/
#endif

View File

@ -123,6 +123,8 @@ static void on_ssh_read(evutil_socket_t fd, short what, void *arg)
if (!ssh_is_connected(client->session)) {
tmate_warn("SSH Disconnected");
event_del(&client->ev_ssh);
/* For graceful tmux client termination */
request_server_termination();
}
@ -190,14 +192,16 @@ static void client_bootstrap(struct tmate_session *_session)
static void handle_sigchld(void)
{
siginfo_t si;
int status;
pid_t pid;
/* TODO cleanup the socket when the client dies */
while (waitid(P_ALL, 0, &si, WEXITED | WNOHANG) >= 0 && si.si_pid) {
tmate_info("Child %d %s (%d)",
si.si_pid,
si.si_code == CLD_EXITED ? "exited" : "killed",
si.si_status);
while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) {
if (WIFEXITED(status))
tmate_info("Child %d exited (%d)", pid, WEXITSTATUS(status));
if (WIFSIGNALED(status))
tmate_info("Child %d killed (%d)", pid, WTERMSIG(status));
if (WIFSTOPPED(status))
tmate_info("Child %d stopped (%d)", pid, WSTOPSIG(status));
}
}

View File

@ -88,8 +88,8 @@ 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 client *c);
extern void tmate_notify_client_left(struct client *c);
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);
@ -200,6 +200,7 @@ struct tmate_session {
struct bufferevent *bev_master;
struct tmate_encoder master_encoder;
struct tmate_decoder master_decoder;
u_int master_sx, master_sy;
/* only for client-pty */
int pty;

2
tmux.h
View File

@ -479,6 +479,7 @@ struct msg_identify_data {
#ifdef TMATE_SLAVE
char ip_address[64];
char pubkey[2048]; /* hopefully enough :) */
#endif
#define IDENTIFY_UTF8 0x1
@ -1387,6 +1388,7 @@ struct client {
#ifdef TMATE_SLAVE
char *ip_address;
char *pubkey;
#endif
};
ARRAY_DECL(clients, struct client *);