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

Allow tmate daemon to specify a list of authorized SSH keys

This commit is contained in:
Nicolas Viennot 2019-11-07 08:10:06 -05:00
parent 48884c95c9
commit e71bd675b5
12 changed files with 386 additions and 48 deletions

View File

@ -175,6 +175,7 @@ dist_tmate_ssh_server_SOURCES = \
signal.c \ signal.c \
status.c \ status.c \
style.c \ style.c \
tmate-auth-keys.c \
tmate-daemon-decoder.c \ tmate-daemon-decoder.c \
tmate-daemon-encoder.c \ tmate-daemon-encoder.c \
tmate-daemon-legacy.c \ tmate-daemon-legacy.c \

View File

@ -401,21 +401,25 @@ client_send_identify(const char *ttynam, const char *cwd)
int fd, flags = client_flags; int fd, flags = client_flags;
pid_t pid; pid_t pid;
proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
#ifdef TMATE_SLAVE #ifdef TMATE_SLAVE
proc_send(client_peer, MSG_IDENTIFY_TMATE_IP_ADDRESS, -1, if (tmate_session->ssh_client.pubkey) {
tmate_session->ssh_client.ip_address, proc_send(client_peer, MSG_IDENTIFY_TMATE_AUTH_PUBKEY, -1,
strlen(tmate_session->ssh_client.ip_address) + 1);
proc_send(client_peer, MSG_IDENTIFY_TMATE_PUBKEY, -1,
tmate_session->ssh_client.pubkey, tmate_session->ssh_client.pubkey,
strlen(tmate_session->ssh_client.pubkey) + 1); strlen(tmate_session->ssh_client.pubkey) + 1);
} else {
proc_send(client_peer, MSG_IDENTIFY_TMATE_AUTH_NONE, -1, NULL, 0);
}
proc_send(client_peer, MSG_IDENTIFY_TMATE_READONLY, proc_send(client_peer, MSG_IDENTIFY_TMATE_READONLY,
-1, &tmate_session->readonly, 1); -1, &tmate_session->readonly, 1);
proc_send(client_peer, MSG_IDENTIFY_TMATE_IP_ADDRESS, -1,
tmate_session->ssh_client.ip_address,
strlen(tmate_session->ssh_client.ip_address) + 1);
#endif #endif
proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
if ((s = getenv("TERM")) == NULL) if ((s = getenv("TERM")) == NULL)
s = ""; s = "";
proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1); proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
@ -658,6 +662,8 @@ client_dispatch_wait(struct imsg *imsg, const char *shellcmd)
case MSG_EXITED: case MSG_EXITED:
proc_exit(client_proc); proc_exit(client_proc);
break; break;
case MSG_TMATE_AUTH_STATUS:
break;
} }
} }

View File

@ -22,6 +22,7 @@
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
#include "tmate.h"
/* /*
* Set an option. * Set an option.
@ -113,6 +114,11 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
else else
valstr = args->argv[1]; valstr = args->argv[1];
#ifdef TMATE_SLAVE
if (!args_has(args, 'u'))
tmate_hook_set_option(optstr, valstr);
#endif
/* Is this a user option? */ /* Is this a user option? */
if (*optstr == '@') if (*optstr == '@')
return (cmd_set_option_user(self, cmdq, optstr, valstr)); return (cmd_set_option_user(self, cmdq, optstr, valstr));

View File

@ -266,7 +266,9 @@ server_client_lost(struct client *c)
server_client_unref(c); server_client_unref(c);
#ifndef TMATE_SLAVE
server_add_accept(0); /* may be more file descriptors now */ server_add_accept(0); /* may be more file descriptors now */
#endif
recalculate_sizes(); recalculate_sizes();
server_check_unattached(); server_check_unattached();
@ -1057,6 +1059,11 @@ server_client_dispatch(struct imsg *imsg, void *arg)
if (c->flags & CLIENT_DEAD) if (c->flags & CLIENT_DEAD)
return; return;
#ifdef TMATE_SLAVE
if (c->flags & CLIENT_EXIT)
return;
#endif
if (imsg == NULL) { if (imsg == NULL) {
server_client_lost(c); server_client_lost(c);
return; return;
@ -1065,6 +1072,24 @@ server_client_dispatch(struct imsg *imsg, void *arg)
data = imsg->data; data = imsg->data;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE; datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
#ifdef TMATE_SLAVE
switch (imsg->hdr.type) {
case MSG_IDENTIFY_TMATE_IP_ADDRESS:
case MSG_IDENTIFY_TMATE_AUTH_NONE:
case MSG_IDENTIFY_TMATE_AUTH_PUBKEY:
case MSG_IDENTIFY_TMATE_READONLY:
server_client_dispatch_identify(c, imsg);
return;
}
if (!(c->flags & CLIENT_TMATE_AUTHENTICATED)) {
control_write(c, "Authentication needed");
tmate_warn("Dropping unauthenticated client");
c->flags |= CLIENT_EXIT;
return;
}
#endif
switch (imsg->hdr.type) { switch (imsg->hdr.type) {
case MSG_IDENTIFY_FLAGS: case MSG_IDENTIFY_FLAGS:
case MSG_IDENTIFY_TERM: case MSG_IDENTIFY_TERM:
@ -1074,13 +1099,18 @@ server_client_dispatch(struct imsg *imsg, void *arg)
case MSG_IDENTIFY_ENVIRON: case MSG_IDENTIFY_ENVIRON:
case MSG_IDENTIFY_CLIENTPID: case MSG_IDENTIFY_CLIENTPID:
case MSG_IDENTIFY_DONE: case MSG_IDENTIFY_DONE:
#ifdef TMATE_SLAVE
case MSG_IDENTIFY_TMATE_IP_ADDRESS:
case MSG_IDENTIFY_TMATE_PUBKEY:
case MSG_IDENTIFY_TMATE_READONLY:
#endif
server_client_dispatch_identify(c, imsg); server_client_dispatch_identify(c, imsg);
break; return;
}
#ifdef TMATE_SLAVE
if (!(c->flags & CLIENT_IDENTIFIED)) {
tmate_warn("dropping unidentified client message: %d", imsg->hdr.type);
return;
}
#endif
switch (imsg->hdr.type) {
case MSG_COMMAND: case MSG_COMMAND:
server_client_dispatch_command(c, imsg); server_client_dispatch_command(c, imsg);
break; break;
@ -1205,6 +1235,15 @@ error:
c->flags |= CLIENT_EXIT; c->flags |= CLIENT_EXIT;
} }
static void handle_tmate_auth(struct client *c)
{
bool allow = tmate_allow_auth(c->pubkey);
if (allow)
c->flags |= CLIENT_TMATE_AUTHENTICATED;
proc_send(c->peer, MSG_TMATE_AUTH_STATUS, -1, &allow, sizeof(allow));
}
/* Handle identify message. */ /* Handle identify message. */
void void
server_client_dispatch_identify(struct client *c, struct imsg *imsg) server_client_dispatch_identify(struct client *c, struct imsg *imsg)
@ -1275,11 +1314,19 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
fatalx("bad MSG_IDENTIFY_TMATE_IP_ADDRESS string"); fatalx("bad MSG_IDENTIFY_TMATE_IP_ADDRESS string");
c->ip_address = xstrdup(data); c->ip_address = xstrdup(data);
break; break;
case MSG_IDENTIFY_TMATE_PUBKEY:
case MSG_IDENTIFY_TMATE_AUTH_NONE:
assert(!c->pubkey);
handle_tmate_auth(c);
break;
case MSG_IDENTIFY_TMATE_AUTH_PUBKEY:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_TMATE_PUBKEY string"); fatalx("bad MSG_IDENTIFY_TMATE_PUBKEY string");
c->pubkey = xstrdup(data); c->pubkey = xstrdup(data);
handle_tmate_auth(c);
break; break;
case MSG_IDENTIFY_TMATE_READONLY: case MSG_IDENTIFY_TMATE_READONLY:
if (datalen != 1) if (datalen != 1)
fatalx("bad MSG_IDENTIFY_TMATE_READONLY size"); fatalx("bad MSG_IDENTIFY_TMATE_READONLY size");
@ -1370,6 +1417,9 @@ server_client_push_stdout(struct client *c)
struct msg_stdout_data data; struct msg_stdout_data data;
size_t sent, left; size_t sent, left;
if (!(c->flags & CLIENT_TMATE_AUTHENTICATED))
return;
left = EVBUFFER_LENGTH(c->stdout_data); left = EVBUFFER_LENGTH(c->stdout_data);
while (left != 0) { while (left != 0) {
sent = left; sent = left;
@ -1411,6 +1461,9 @@ server_client_push_stderr(struct client *c)
struct msg_stderr_data data; struct msg_stderr_data data;
size_t sent, left; size_t sent, left;
if (!(c->flags & CLIENT_TMATE_AUTHENTICATED))
return;
if (c->stderr_data == c->stdout_data) { if (c->stderr_data == c->stdout_data) {
server_client_push_stdout(c); server_client_push_stdout(c);
return; return;

View File

@ -190,9 +190,8 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
#ifndef TMATE_SLAVE #ifndef TMATE_SLAVE
status_prompt_load_history(); status_prompt_load_history();
#endif
server_add_accept(0); server_add_accept(0);
#endif
proc_loop(server_proc, server_loop); proc_loop(server_proc, server_loop);
#ifndef TMATE_SLAVE #ifndef TMATE_SLAVE
@ -379,6 +378,7 @@ server_signal(int sig)
case SIGCHLD: case SIGCHLD:
server_child_signal(); server_child_signal();
break; break;
#ifndef TMATE_SLAVE
case SIGUSR1: case SIGUSR1:
event_del(&server_ev_accept); event_del(&server_ev_accept);
fd = server_create_socket(); fd = server_create_socket();
@ -389,6 +389,7 @@ server_signal(int sig)
} }
server_add_accept(0); server_add_accept(0);
break; break;
#endif
} }
} }

225
tmate-auth-keys.c Normal file
View File

@ -0,0 +1,225 @@
#include <sys/socket.h>
#include <sys/un.h>
#include "tmate.h"
static void reset_and_enable_authorized_keys(void)
{
ssh_key *keys = tmate_session->authorized_keys;
if (keys) {
for (ssh_key *k = keys; *k; k++)
ssh_key_free(*k);
free(keys);
}
keys = xreallocarray(NULL, sizeof(ssh_key), 1);
keys[0] = NULL;
tmate_session->authorized_keys = keys;
}
static ssh_key import_ssh_pubkey64(const char *_keystr)
{
/* key is formatted as "type base64_key" */
char * const keystr = xstrdup(_keystr);
char *s = keystr;
ssh_key ret = NULL;
char *key_type = strsep(&s, " ");
char *key_content = strsep(&s, " ");
if (!key_content)
goto out;
enum ssh_keytypes_e type = ssh_key_type_from_name(key_type);
if (type == SSH_KEYTYPE_UNKNOWN)
goto out;
if (ssh_pki_import_pubkey_base64(key_content, type, &ret) != SSH_OK) {
ret = NULL;
goto out;
}
out:
free(keystr);
return ret;
}
int get_num_authorized_keys(ssh_key *keys)
{
if (!keys)
return 0;
int count = 0;
for (ssh_key *k = keys; *k; k++)
count++;
return count;
}
static void append_authorized_key(const char *keystr)
{
if (!tmate_session->authorized_keys)
reset_and_enable_authorized_keys();
ssh_key pkey = import_ssh_pubkey64(keystr);
if (!pkey)
return;
ssh_key *keys = tmate_session->authorized_keys;
int count = get_num_authorized_keys(keys);
keys = xreallocarray(keys, sizeof(ssh_key), count+2);
tmate_session->authorized_keys = keys;
keys[count++] = pkey;
keys[count] = NULL;
}
static void tmate_set(char *key, char *value)
{
if (!strcmp(key, "authorized_keys"))
append_authorized_key(value);
}
void tmate_hook_set_option(const char *name, const char *val)
{
if (!strcmp(name, "tmate-authorized-keys")) {
reset_and_enable_authorized_keys();
} else if (!strcmp(name, "tmate-set")) {
char *key_value = xstrdup(val);
char *s = key_value;
char *key = strsep(&s, "=");
char *value = s;
if (value)
tmate_set(key, value);
free(key_value);
}
}
bool tmate_allow_auth(const char *pubkey)
{
/*
* Note that we don't accept connections on the tmux socket until we
* get the tmate ready message.
*/
if (!tmate_session->authorized_keys)
return true;
if (!pubkey)
return false;
ssh_key client_pkey = import_ssh_pubkey64(pubkey);
if (!client_pkey)
return false;
bool ret = false;
for (ssh_key *k = tmate_session->authorized_keys; *k; k++) {
if (!ssh_key_cmp(client_pkey, *k, SSH_KEY_CMP_PUBLIC)) {
ret = true;
break;
}
}
ssh_key_free(client_pkey);
return ret;
}
static int write_all(int fd, const char *buf, size_t len)
{
for (size_t i = 0; i < len;) {
size_t ret = write(fd, buf+i, len-i);
if (ret <= 0)
return -1;
i += ret;
}
return 0;
}
static int read_all(int fd, char *buf, size_t len)
{
for (size_t i = 0; i < len;) {
size_t ret = read(fd, buf+i, len-i);
if (ret <= 0)
return -1;
i += ret;
}
return 0;
}
/*
* The following is executed in the context of the SSH server
*/
bool would_tmate_session_allow_auth(const char *token, const char *pubkey)
{
/*
* The existance of this function is a bit unpleasant:
* In order to have the right SSH public key from the SSH client,
* we need to ask the tmate session for a match. Denying the key
* to the SSH client will make it cycle through its keys.
* We briefly connect to the session to get an answer.
*
* Note that the client will get reauthenticated later (see
* server-client.c when identifying the client).
*/
int sock_fd = -1;
int ret = true;
if (tmate_validated_session_token(token) < 0)
goto out;
char *sock_path = get_socket_path(token);
struct sockaddr_un sa;
memset(&sa, 0, sizeof(sa));
sa.sun_family = AF_UNIX;
size_t size = strlcpy(sa.sun_path, sock_path, sizeof(sa.sun_path));
free(sock_path);
if (size >= sizeof sa.sun_path)
goto out;
sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0)
goto out;
if (connect(sock_fd, (struct sockaddr *)&sa, sizeof sa) == -1)
goto out;
struct imsg_hdr hdr = {
.type = pubkey ? MSG_IDENTIFY_TMATE_AUTH_PUBKEY :
MSG_IDENTIFY_TMATE_AUTH_NONE,
.len = IMSG_HEADER_SIZE + (pubkey ? strlen(pubkey)+1 : 0),
.flags = 0,
.peerid = PROTOCOL_VERSION,
.pid = -1,
};
if (write_all(sock_fd, (void*)&hdr, sizeof(hdr)) < 0)
goto out;
if (pubkey) {
if (write_all(sock_fd, pubkey, strlen(pubkey)+1) < 0)
goto out;
}
struct {
struct imsg_hdr hdr;
bool allow;
} __packed recv_msg;
if (read_all(sock_fd, (void*)&recv_msg, sizeof(recv_msg)) < 0)
goto out;
if (recv_msg.hdr.type == MSG_TMATE_AUTH_STATUS &&
recv_msg.hdr.len == sizeof(recv_msg))
ret = recv_msg.allow;
tmate_info("(preauth) allow=%d", ret);
out:
if (sock_fd != -1)
close(sock_fd);
return ret;
}

View File

@ -6,15 +6,29 @@
char *tmate_left_status, *tmate_right_status; char *tmate_left_status, *tmate_right_status;
static void tmate_ready(struct tmate_session *session,
__unused struct tmate_unpacker *uk)
{
/* This message is also used by the websocket server */
/*
* We only start accepting connections once the host is ready, this
* way we have the authorized keys loaded correctly
*/
if (session->authorized_keys) {
int count = get_num_authorized_keys(session->authorized_keys);
tmate_info("Restricting ssh access, num_keys=%d", count);
}
server_add_accept(0);
}
static void tmate_header(struct tmate_session *session, static void tmate_header(struct tmate_session *session,
struct tmate_unpacker *uk) struct tmate_unpacker *uk)
{ {
char *ssh_conn_str; char *ssh_conn_str;
session->client_protocol_version = unpack_int(uk); session->client_protocol_version = unpack_int(uk);
if (session->client_protocol_version <= 4) {
session->daemon_encoder.mpac_version = 4;
}
if (session->client_protocol_version >= 3) { if (session->client_protocol_version >= 3) {
session->client_version = unpack_string(uk); session->client_version = unpack_string(uk);
@ -22,6 +36,15 @@ static void tmate_header(struct tmate_session *session,
session->client_version = xstrdup("1.8.5"); session->client_version = xstrdup("1.8.5");
} }
if (session->client_protocol_version < 6) {
/* older clients don't send a ready message */
tmate_ready(session, NULL);
}
if (session->client_protocol_version < 5) {
session->daemon_encoder.mpac_version = 4;
}
tmate_notice("Daemon header: client version: %s, protocol version: %d", tmate_notice("Daemon header: client version: %s, protocol version: %d",
session->client_version, session->client_protocol_version); session->client_version, session->client_protocol_version);
@ -45,13 +68,6 @@ static void tmate_header(struct tmate_session *session,
tmate_send_client_ready(); tmate_send_client_ready();
} }
static void tmate_ready(__unused struct tmate_session *session,
__unused struct tmate_unpacker *uk)
{
/* used by the websocket */
}
extern u_int next_window_pane_id; extern u_int next_window_pane_id;
static void tmate_sync_window_panes(struct window *w, static void tmate_sync_window_panes(struct window *w,

View File

@ -1,7 +1,7 @@
#include "tmate.h" #include "tmate.h"
#include "tmate-protocol.h" #include "tmate-protocol.h"
#define pack(what, ...) _pack(&tmate_session->daemon_encoder, what, __VA_ARGS__) #define pack(what, ...) _pack(&tmate_session->daemon_encoder, what, ##__VA_ARGS__)
static void __tmate_notify(const char *msg) static void __tmate_notify(const char *msg)
{ {

View File

@ -127,7 +127,7 @@ static ssh_channel channel_open_request_cb(ssh_session session, void *userdata)
static int auth_pubkey_cb(__unused ssh_session session, static int auth_pubkey_cb(__unused ssh_session session,
const char *user, const char *user,
struct ssh_key_struct *pubkey, ssh_key pubkey,
char signature_state, void *userdata) char signature_state, void *userdata)
{ {
struct tmate_ssh_client *client = userdata; struct tmate_ssh_client *client = userdata;
@ -135,9 +135,24 @@ static int auth_pubkey_cb(__unused ssh_session session,
switch (signature_state) { switch (signature_state) {
case SSH_PUBLICKEY_STATE_VALID: case SSH_PUBLICKEY_STATE_VALID:
client->username = xstrdup(user); client->username = xstrdup(user);
if (ssh_pki_export_pubkey_base64(pubkey, &client->pubkey) != SSH_OK)
const char *key_type = ssh_key_type_to_char(ssh_key_type(pubkey));
char *b64_key;
if (ssh_pki_export_pubkey_base64(pubkey, &b64_key) != SSH_OK)
tmate_fatal("error getting public key"); tmate_fatal("error getting public key");
char *pubkey64;
xasprintf(&pubkey64, "%s %s", key_type, b64_key);
free(b64_key);
if (!would_tmate_session_allow_auth(user, pubkey64)) {
free(pubkey64);
return SSH_AUTH_DENIED;
}
client->pubkey = pubkey64;
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
case SSH_PUBLICKEY_STATE_NONE: case SSH_PUBLICKEY_STATE_NONE:
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
@ -146,14 +161,15 @@ static int auth_pubkey_cb(__unused ssh_session session,
} }
} }
static int auth_none_cb(ssh_session session, const char *user, void *userdata) static int auth_none_cb(__unused ssh_session session, const char *user, void *userdata)
{ {
(void)session;
struct tmate_ssh_client *client = userdata; struct tmate_ssh_client *client = userdata;
if (!would_tmate_session_allow_auth(user, NULL))
return SSH_AUTH_DENIED;
client->username = xstrdup(user); client->username = xstrdup(user);
client->pubkey = xstrdup("none"); client->pubkey = NULL;
return SSH_AUTH_SUCCESS; return SSH_AUTH_SUCCESS;
} }

View File

@ -16,7 +16,14 @@
#define CONTROL_PROTOCOL_VERSION 2 #define CONTROL_PROTOCOL_VERSION 2
#define pack(what, ...) _pack(&tmate_session->websocket_encoder, what, __VA_ARGS__) #define pack(what, ...) _pack(&tmate_session->websocket_encoder, what, ##__VA_ARGS__)
#define pack_string_or_nil(str) ({ \
if (str) \
pack(string, str); \
else \
pack(nil); \
})
static void ctl_daemon_fwd_msg(__unused struct tmate_session *session, static void ctl_daemon_fwd_msg(__unused struct tmate_session *session,
struct tmate_unpacker *uk) struct tmate_unpacker *uk)
@ -205,7 +212,7 @@ void tmate_websocket_exec(struct tmate_session *session, const char *command)
pack(int, TMATE_CTL_EXEC); pack(int, TMATE_CTL_EXEC);
pack(string, client->username); pack(string, client->username);
pack(string, client->ip_address); pack(string, client->ip_address);
pack(string, client->pubkey); pack_string_or_nil(client->pubkey);
pack(string, command); pack(string, command);
} }
@ -223,7 +230,7 @@ void tmate_notify_client_join(__unused struct tmate_session *session,
pack(int, TMATE_CTL_CLIENT_JOIN); pack(int, TMATE_CTL_CLIENT_JOIN);
pack(int, c->id); pack(int, c->id);
pack(string, c->ip_address); pack(string, c->ip_address);
pack(string, c->pubkey); pack_string_or_nil(c->pubkey);
pack(boolean, c->readonly); pack(boolean, c->readonly);
} }
@ -270,7 +277,7 @@ void tmate_send_websocket_header(struct tmate_session *session)
pack(int, TMATE_CTL_HEADER); pack(int, TMATE_CTL_HEADER);
pack(int, CONTROL_PROTOCOL_VERSION); pack(int, CONTROL_PROTOCOL_VERSION);
pack(string, session->ssh_client.ip_address); pack(string, session->ssh_client.ip_address);
pack(string, session->ssh_client.pubkey); pack_string_or_nil(session->ssh_client.pubkey);
pack(string, session->session_token); pack(string, session->session_token);
pack(string, session->session_token_ro); pack(string, session->session_token_ro);

10
tmate.h
View File

@ -33,6 +33,12 @@ extern void printflike(2, 3) tmate_log(int level, const char *msg, ...);
exit(1); \ exit(1); \
}) })
/* tmate-auth-keys.c */
extern void tmate_hook_set_option(const char *name, const char *val);
extern bool tmate_allow_auth(const char *pubkey);
extern bool would_tmate_session_allow_auth(const char *token, const char *pubkey);
extern int get_num_authorized_keys(ssh_key *keys);
/* tmate-msgpack.c */ /* tmate-msgpack.c */
typedef void tmate_encoder_write_cb(void *userdata, struct evbuffer *buffer); typedef void tmate_encoder_write_cb(void *userdata, struct evbuffer *buffer);
@ -57,7 +63,7 @@ extern void msgpack_pack_boolean(msgpack_packer *pk, bool value);
extern int _msgpack_pack_object(msgpack_packer *pk, msgpack_object d); extern int _msgpack_pack_object(msgpack_packer *pk, msgpack_object d);
#define msgpack_pack_object _msgpack_pack_object #define msgpack_pack_object _msgpack_pack_object
#define _pack(enc, what, ...) msgpack_pack_##what(&(enc)->pk, __VA_ARGS__) #define _pack(enc, what, ...) msgpack_pack_##what(&(enc)->pk, ##__VA_ARGS__)
struct tmate_unpacker; struct tmate_unpacker;
struct tmate_decoder; struct tmate_decoder;
@ -222,6 +228,8 @@ struct tmate_session {
int tmux_socket_fd; int tmux_socket_fd;
/* only for role deamon */ /* only for role deamon */
ssh_key *authorized_keys; /* array with NULL as last element */
const char *session_token; const char *session_token;
const char *session_token_ro; const char *session_token_ro;
const char *obfuscated_session_token; /* for logging purposes */ const char *obfuscated_session_token; /* for logging purposes */

15
tmux.h
View File

@ -414,13 +414,6 @@ enum msgtype {
MSG_IDENTIFY_CLIENTPID, MSG_IDENTIFY_CLIENTPID,
MSG_IDENTIFY_CWD, MSG_IDENTIFY_CWD,
#ifdef TMATE_SLAVE
/* Next time put this after TMATE_LATENCY */
MSG_IDENTIFY_TMATE_IP_ADDRESS,
MSG_IDENTIFY_TMATE_PUBKEY,
MSG_IDENTIFY_TMATE_READONLY,
#endif
MSG_COMMAND = 200, MSG_COMMAND = 200,
MSG_DETACH, MSG_DETACH,
MSG_DETACHKILL, MSG_DETACHKILL,
@ -440,7 +433,12 @@ enum msgtype {
MSG_WAKEUP, MSG_WAKEUP,
#ifdef TMATE_SLAVE #ifdef TMATE_SLAVE
MSG_LATENCY = 300 MSG_LATENCY = 300,
MSG_IDENTIFY_TMATE_IP_ADDRESS,
MSG_IDENTIFY_TMATE_AUTH_NONE,
MSG_IDENTIFY_TMATE_AUTH_PUBKEY,
MSG_IDENTIFY_TMATE_READONLY,
MSG_TMATE_AUTH_STATUS,
#endif #endif
}; };
@ -1307,6 +1305,7 @@ struct client {
#define CLIENT_STATUSFORCE 0x80000 #define CLIENT_STATUSFORCE 0x80000
#ifdef TMATE_SLAVE #ifdef TMATE_SLAVE
#define CLIENT_TMATE_NOTIFIED_JOIN 0x10000000 #define CLIENT_TMATE_NOTIFIED_JOIN 0x10000000
#define CLIENT_TMATE_AUTHENTICATED 0x20000000
#endif #endif
int flags; int flags;
struct key_table *keytable; struct key_table *keytable;