diff --git a/options-table.c b/options-table.c index 504bcfca..342fd172 100644 --- a/options-table.c +++ b/options-table.c @@ -176,6 +176,11 @@ const struct options_table_entry session_options_table[] = { .default_num = 30000 }, + { .name = "tmate-identity", + .type = OPTIONS_TABLE_STRING, + .default_str = "" + }, + { .name = "history-limit", .type = OPTIONS_TABLE_NUMBER, .minimum = 0, diff --git a/server.c b/server.c index c99ce8e4..6620c78b 100644 --- a/server.c +++ b/server.c @@ -187,8 +187,7 @@ server_start(int lockfd, char *lockfile) } } - tmate_session_start(); - + tmate_session_init(); cmdq_continue(cfg_cmd_q); server_add_accept(0); @@ -200,6 +199,7 @@ server_start(int lockfd, char *lockfile) set_signals(server_signal_callback); + tmate_session_start(); server_loop(); exit(0); } diff --git a/tmate-session.c b/tmate-session.c index 93f82955..bbca4c12 100644 --- a/tmate-session.c +++ b/tmate-session.c @@ -92,7 +92,7 @@ static void lookup_and_connect(void) &hints, dns_cb, NULL); } -void tmate_session_start(void) +void tmate_session_init(void) { tmate_catch_sigsegv(); @@ -100,8 +100,17 @@ void tmate_session_start(void) tmate_encoder_init(&tmate_session.encoder); tmate_decoder_init(&tmate_session.decoder); - lookup_and_connect(); - /* The header will be written as soon as the first client connects */ tmate_write_header(); } + +void tmate_session_start(void) +{ + /* We split init and start because: + * - We need to process the tmux config file during the connection as + * we are setting up the tmate identity. + * - While we are parsing the config file, we need to be able to + * serialize it, and so we need a worker encoder. + */ + lookup_and_connect(); +} diff --git a/tmate-ssh-client.c b/tmate-ssh-client.c index 2429391f..50842d97 100644 --- a/tmate-ssh-client.c +++ b/tmate-ssh-client.c @@ -83,8 +83,25 @@ static void connection_complete(struct tmate_ssh_client *connected_client) } } +static char *get_identity(void) +{ + char *identity; + + identity = options_get_string(&global_s_options, "tmate-identity"); + if (!strlen(identity)) + return NULL; + + if (strchr(identity, '/')) + identity = xstrdup(identity); + else + xasprintf(&identity, "%%d/%s", identity); + + return identity; +} + static void on_session_event(struct tmate_ssh_client *client) { + char *identity; ssh_key pubkey; int key_type; unsigned char *hash; @@ -121,6 +138,11 @@ static void on_session_event(struct tmate_ssh_client *client) ssh_options_set(session, SSH_OPTIONS_USER, "tmate"); ssh_options_set(session, SSH_OPTIONS_COMPRESSION, "yes"); + if ((identity = get_identity())) { + ssh_options_set(session, SSH_OPTIONS_IDENTITY, identity); + free(identity); + } + client->state = SSH_CONNECT; /* fall through */ diff --git a/tmate.h b/tmate.h index 7969dbfe..687fd7e6 100644 --- a/tmate.h +++ b/tmate.h @@ -144,6 +144,7 @@ struct tmate_session { }; extern struct tmate_session tmate_session; +extern void tmate_session_init(void); extern void tmate_session_start(void); /* tmate-debug.c */