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:
parent
51ba50ac0d
commit
6c62b10e0a
5
client.c
5
client.c
@ -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
1
log.c
@ -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)
|
||||
|
7
resize.c
7
resize.c
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
5
tmate.h
5
tmate.h
@ -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
2
tmux.h
@ -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 *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user