mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Connections are now using tokens
This commit is contained in:
parent
3b4e6bb9cc
commit
4ae8ba3270
11
client.c
11
client.c
@ -32,6 +32,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "tmate.h"
|
||||
|
||||
struct imsgbuf client_ibuf;
|
||||
struct event client_event;
|
||||
@ -206,8 +207,8 @@ client_main(int argc, char **argv, int flags)
|
||||
}
|
||||
|
||||
#ifdef TMATE_SLAVE
|
||||
cmdflags &= ~CMD_STARTSERVER;
|
||||
#endif
|
||||
fd = tmux_socket_fd;
|
||||
#else
|
||||
|
||||
/*
|
||||
* Check if this could be a nested session, if the command can't nest:
|
||||
@ -227,6 +228,7 @@ client_main(int argc, char **argv, int flags)
|
||||
fprintf(stderr, "failed to connect to server\n");
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set process title, log and signals now this is the client. */
|
||||
#ifdef HAVE_SETPROCTITLE
|
||||
@ -293,8 +295,9 @@ client_main(int argc, char **argv, int flags)
|
||||
|
||||
/* Print the exit message, if any, and exit. */
|
||||
if (client_attached) {
|
||||
if (client_exitreason != CLIENT_EXIT_NONE && !login_shell)
|
||||
printf("[%s]\n", client_exit_message());
|
||||
if (client_exitreason != CLIENT_EXIT_NONE && !login_shell) {
|
||||
printf("[%s]\r\n", client_exit_message());
|
||||
}
|
||||
|
||||
ppid = getppid();
|
||||
if (client_exittype == MSG_DETACHKILL && ppid > 1)
|
||||
|
11
server.c
11
server.c
@ -97,9 +97,7 @@ server_create_socket(void)
|
||||
fatal("listen failed");
|
||||
setblocking(fd, 0);
|
||||
|
||||
server_update_socket();
|
||||
|
||||
return (fd);
|
||||
server_update_socket(); return (fd);
|
||||
}
|
||||
|
||||
/* Fork new server. */
|
||||
@ -162,9 +160,10 @@ server_start(int lockfd, char *lockfile)
|
||||
setproctitle("server (%s)", socket_path);
|
||||
#endif
|
||||
|
||||
#ifdef TMATE_SLAVE
|
||||
server_fd = tmux_socket_fd;
|
||||
#else
|
||||
server_fd = server_create_socket();
|
||||
|
||||
#ifndef TMATE_SLAVE
|
||||
server_client_create(pair[1]);
|
||||
|
||||
unlink(lockfile);
|
||||
@ -397,10 +396,12 @@ server_signal_callback(int sig, unused short events, unused void *data)
|
||||
server_child_signal();
|
||||
break;
|
||||
case SIGUSR1:
|
||||
#ifndef TMATE_SLAVE
|
||||
event_del(&server_ev_accept);
|
||||
close(server_fd);
|
||||
server_fd = server_create_socket();
|
||||
server_add_accept(0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
134
tmate-slave.c
134
tmate-slave.c
@ -1,8 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include "tmate.h"
|
||||
|
||||
struct tmate_encoder *tmate_encoder;
|
||||
int tmux_socket_fd;
|
||||
const char *tmate_session_token;
|
||||
|
||||
extern int server_create_socket(void);
|
||||
extern int client_connect(char *path, int start_server);
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: tmate-slave [-p PORT]\n");
|
||||
@ -14,8 +22,6 @@ int main(int argc, char **argv)
|
||||
int port = 22;
|
||||
char *log_path = NULL; /* stderr */
|
||||
|
||||
strcpy(socket_path, "/tmp/tmate-slave");
|
||||
|
||||
while ((opt = getopt(argc, argv, "p:l:v")) != -1) {
|
||||
switch (opt) {
|
||||
case 'p':
|
||||
@ -38,16 +44,62 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tmate_encoder *tmate_encoder;
|
||||
|
||||
void tmate_spawn_slave_server(struct tmate_ssh_client *client)
|
||||
static void set_session_token(const char *token)
|
||||
{
|
||||
tmate_session_token = xstrdup(token);
|
||||
strcpy(socket_path, "/tmp/tmate-slave-");
|
||||
strcat(socket_path, token);
|
||||
}
|
||||
|
||||
static char tmate_token_digits[] = "abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789";
|
||||
#define NUM_DIGITS (sizeof(tmate_token_digits) - 1)
|
||||
|
||||
static char *get_random_token(void)
|
||||
{
|
||||
int i;
|
||||
char *token = xmalloc(TMATE_TOKEN_LEN + 1);
|
||||
|
||||
ssh_get_random(token, TMATE_TOKEN_LEN, 0);
|
||||
for (i = 0; i < TMATE_TOKEN_LEN; i++)
|
||||
token[i] = tmate_token_digits[token[i] % NUM_DIGITS];
|
||||
token[i] = 0;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
static int validate_token(const char *token)
|
||||
{
|
||||
int len = strlen(token);
|
||||
int i;
|
||||
|
||||
if (len != TMATE_TOKEN_LEN)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!strchr(tmate_token_digits, token[i]))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tmate_spawn_slave_server(struct tmate_ssh_client *client)
|
||||
{
|
||||
char *token;
|
||||
struct tmate_encoder encoder;
|
||||
struct tmate_decoder decoder;
|
||||
|
||||
tmate_debug("Spawn tmux slave server");
|
||||
token = get_random_token();
|
||||
set_session_token(token);
|
||||
free(token);
|
||||
|
||||
ev_base = osdep_event_init();
|
||||
tmate_debug("Spawning tmux slave server %s", tmate_session_token);
|
||||
|
||||
tmux_socket_fd = server_create_socket();
|
||||
if (tmux_socket_fd < 0)
|
||||
tmate_fatal("Cannot create to the tmux socket");
|
||||
|
||||
tmate_encoder_init(&encoder);
|
||||
tmate_decoder_init(&decoder);
|
||||
@ -59,22 +111,68 @@ void tmate_spawn_slave_server(struct tmate_ssh_client *client)
|
||||
/* never reached */
|
||||
}
|
||||
|
||||
void tmate_spawn_slave_client(struct tmate_ssh_client *ssh_client)
|
||||
static void ssh_echo(struct tmate_ssh_client *ssh_client,
|
||||
const char *str)
|
||||
{
|
||||
ssh_channel_write(ssh_client->channel, str, strlen(str));
|
||||
}
|
||||
|
||||
#define BAD_TOKEN_ERROR_STR \
|
||||
" " "\r\n" \
|
||||
" Dear guest," "\r\n" \
|
||||
" " "\r\n" \
|
||||
" There isn't much I can do without a valid session token." "\r\n" \
|
||||
" Feel free to reach out if you are having issues." "\r\n" \
|
||||
" " "\r\n" \
|
||||
" Thanks," "\r\n" \
|
||||
" Nico" "\r\n" \
|
||||
" " "\r\n"
|
||||
|
||||
#define EXPIRED_TOKEN_ERROR_STR \
|
||||
" " "\r\n" \
|
||||
" Dear guest," "\r\n" \
|
||||
" " "\r\n" \
|
||||
" The provided session token is invalid, or has expired." "\r\n" \
|
||||
" Feel free to reach out if you are having issues." "\r\n" \
|
||||
" " "\r\n" \
|
||||
" Thanks," "\r\n" \
|
||||
" Nico" "\r\n" \
|
||||
" " "\r\n"
|
||||
|
||||
static void random_sleep(void)
|
||||
{
|
||||
usleep(50000 + (rand() % 50000));
|
||||
}
|
||||
|
||||
static void tmate_spawn_slave_client(struct tmate_ssh_client *ssh_client)
|
||||
{
|
||||
struct tmate_ssh_client_pty _client;
|
||||
struct tmate_ssh_client_pty *client = &_client;
|
||||
char *argv[] = {(char *)"attach", NULL};
|
||||
char *token = ssh_client->username;
|
||||
int slave_pty;
|
||||
int ret;
|
||||
char *argv[] = {(char *)"attach", NULL};
|
||||
|
||||
if (validate_token(token) < 0) {
|
||||
ssh_echo(ssh_client, BAD_TOKEN_ERROR_STR);
|
||||
tmate_fatal("Bad token");
|
||||
}
|
||||
|
||||
set_session_token(token);
|
||||
|
||||
tmate_debug("Spawn tmux slave client %s", tmate_session_token);
|
||||
|
||||
tmux_socket_fd = client_connect(socket_path, 0);
|
||||
if (tmux_socket_fd < 0) {
|
||||
random_sleep(); /* for timing attacks */
|
||||
ssh_echo(ssh_client, EXPIRED_TOKEN_ERROR_STR);
|
||||
tmate_fatal("Expired token");
|
||||
}
|
||||
|
||||
client->session = ssh_client->session;
|
||||
client->channel = ssh_client->channel;
|
||||
client->winsize_pty = ssh_client->winsize_pty;
|
||||
|
||||
tmate_debug("Spawn tmux slave client");
|
||||
|
||||
ev_base = osdep_event_init();
|
||||
|
||||
if (openpty(&client->pty, &slave_pty, NULL, NULL, NULL) < 0)
|
||||
tmate_fatal("Cannot allocate pty");
|
||||
|
||||
@ -89,3 +187,13 @@ void tmate_spawn_slave_client(struct tmate_ssh_client *ssh_client)
|
||||
tmate_flush_pty(client);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
void tmate_spawn_slave(struct tmate_ssh_client *client)
|
||||
{
|
||||
ev_base = osdep_event_init();
|
||||
|
||||
if (client->role == TMATE_ROLE_SERVER)
|
||||
tmate_spawn_slave_server(client);
|
||||
else
|
||||
tmate_spawn_slave_client(client);
|
||||
}
|
||||
|
@ -105,18 +105,19 @@ static int init_client_step(struct tmate_ssh_client *client,
|
||||
if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL &&
|
||||
ssh_message_subtype(msg) == SSH_CHANNEL_REQUEST_SUBSYSTEM &&
|
||||
!strcmp(ssh_message_channel_request_subsystem(msg), "tmate")) {
|
||||
alarm(0);
|
||||
ssh_message_channel_request_reply_success(msg);
|
||||
tmate_spawn_slave_server(client);
|
||||
/* never reached */
|
||||
client->role = TMATE_ROLE_SERVER;
|
||||
}
|
||||
|
||||
/* shell request (slave client) */
|
||||
if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL &&
|
||||
ssh_message_subtype(msg) == SSH_CHANNEL_REQUEST_SHELL) {
|
||||
client->role = TMATE_ROLE_CLIENT;
|
||||
}
|
||||
|
||||
if (client->role) {
|
||||
alarm(0);
|
||||
ssh_message_channel_request_reply_success(msg);
|
||||
tmate_spawn_slave_client(client);
|
||||
tmate_spawn_slave(client);
|
||||
/* never reached */
|
||||
}
|
||||
|
||||
|
13
tmate.h
13
tmate.h
@ -60,10 +60,15 @@ extern void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len);
|
||||
typedef struct ssh_session_struct* ssh_session;
|
||||
typedef struct ssh_channel_struct* ssh_channel;
|
||||
|
||||
#define TMATE_ROLE_SERVER 1
|
||||
#define TMATE_ROLE_CLIENT 2
|
||||
|
||||
struct tmate_ssh_client {
|
||||
ssh_session session;
|
||||
ssh_channel channel;
|
||||
|
||||
int role;
|
||||
|
||||
struct tmate_encoder *encoder;
|
||||
struct tmate_decoder *decoder;
|
||||
|
||||
@ -102,10 +107,12 @@ extern void tmate_ssh_server_main(int port);
|
||||
|
||||
/* tmate-slave.c */
|
||||
|
||||
extern struct tmate_encoder *tmate_encoder;
|
||||
#define TMATE_TOKEN_LEN 25
|
||||
|
||||
extern void tmate_spawn_slave_server(struct tmate_ssh_client *client);
|
||||
extern void tmate_spawn_slave_client(struct tmate_ssh_client *client);
|
||||
extern struct tmate_encoder *tmate_encoder;
|
||||
extern int tmux_socket_fd;
|
||||
|
||||
extern void tmate_spawn_slave(struct tmate_ssh_client *client);
|
||||
|
||||
/* tmate-debug.c */
|
||||
extern void tmate_print_trace(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user