1
0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2020-11-18 19:53:51 -08:00
- Log only to syslog or stderr
- Removed the record/replay
- added ECDSA keys
This commit is contained in:
Nicolas Viennot 2015-09-18 01:21:36 -04:00
parent c7c436eff1
commit 31cc091823
9 changed files with 151 additions and 297 deletions

View File

@ -181,7 +181,6 @@ dist_tmate_slave_SOURCES = \
tmate-debug.c \ tmate-debug.c \
tmate-decoder.c \ tmate-decoder.c \
tmate-encoder.c \ tmate-encoder.c \
tmate-replayer.c \
tmate-slave.c \ tmate-slave.c \
tmate-ssh-client-pty.c \ tmate-ssh-client-pty.c \
tmate-ssh-client.c \ tmate-ssh-client.c \

View File

@ -4,10 +4,10 @@ gen_key() {
ks="${keytype}_" ks="${keytype}_"
key="keys/ssh_host_${ks}key" key="keys/ssh_host_${ks}key"
if [ ! -e "${key}" ] ; then if [ ! -e "${key}" ] ; then
ssh-keygen -t ${keytype} -f "${key}" -N '' ssh-keygen -t ${keytype} -f "${key}" -N '' -E md5
return $? return $?
fi fi
} }
mkdir -p keys mkdir -p keys
gen_key dsa && gen_key rsa && gen_key ecdsa || exit 1 gen_key rsa && gen_key ecdsa || exit 1

144
log.c
View File

@ -29,89 +29,68 @@
#include "tmux.h" #include "tmux.h"
#include "tmate.h" #include "tmate.h"
/* Log file, if needed. */ FILE *log_file;
FILE *log_file;
/* Debug level. */ struct logging_settings {
int log_level = 0; const char *program_name;
bool use_syslog;
int log_level;
};
static struct logging_settings log_settings;
void log_event_cb(int, const char *); void log_event_cb(int, const char *);
void log_vwrite(const char *, va_list); void log_vwrite(int, const char *, va_list);
__dead void log_vfatal(const char *, va_list); __dead void log_vfatal(const char *, va_list);
/* Log callback for libevent. */
void void
log_event_cb(unused int severity, const char *msg) log_event_cb(unused int severity, const char *msg)
{ {
log_warnx("%s", msg); log_warnx("%s", msg);
} }
/* Open logging to file. */ void init_logging(const char *program_name, bool use_syslog, int log_level)
void
log_open(int level, const char *path)
{ {
FILE *f; log_settings.log_level = log_level;
log_settings.use_syslog = use_syslog;
log_settings.program_name = xstrdup(program_name);
if (path) { if (use_syslog) {
f = fopen(path, "a"); openlog(program_name, LOG_CONS | LOG_PID, LOG_USER);
if (!f) { setlogmask(LOG_UPTO(log_level));
if (log_file) {
log_info("cannot reopen log file");
return;
}
fprintf(stderr, "cannot open log file %s\n", path);
exit(1);
}
} else { } else {
f = fdopen(dup(STDERR_FILENO), "a"); log_file = fdopen(dup(STDERR_FILENO), "a");
if (!log_file)
exit(1);
} }
if (log_file)
fclose(log_file);
log_file = f;
log_level = level;
setlinebuf(log_file);
event_set_log_callback(log_event_cb); event_set_log_callback(log_event_cb);
tzset();
}
/* Close logging. */
void
log_close(void)
{
if (log_file != NULL)
fclose(log_file);
event_set_log_callback(NULL);
} }
/* Write a log message. */ /* Write a log message. */
void void
log_vwrite(const char *msg, va_list ap) log_vwrite(int level, const char *msg, va_list ap)
{ {
char time_str[100]; char *fmt = NULL;
time_t now;
struct tm *tm;
char *fmt; if (log_settings.log_level < level)
if (log_file == NULL)
return; return;
/* XXX Should we do UTC instead of local time? */ if (tmate_session_token) {
now = time(NULL); if (asprintf(&fmt, "[%s] %s", tmate_session_token, msg) < 0)
tm = localtime(&now); exit(1);
msg = fmt;
}
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm); if (log_settings.use_syslog) {
vsyslog(level, msg, ap);
} else {
fprintf(log_file, "<%d> ", level);
vfprintf(log_file, msg, ap);
fprintf(log_file, "\n");
fflush(log_file);
}
if (asprintf(&fmt, "%s [%s] %s\n", time_str, tmate_session_token, msg) == -1)
exit(1);
if (vfprintf(log_file, fmt, ap) == -1)
exit(1);
fflush(log_file);
free(fmt); free(fmt);
} }
@ -125,7 +104,7 @@ log_warn(const char *msg, ...)
va_start(ap, msg); va_start(ap, msg);
if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1) if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
exit(1); exit(1);
log_vwrite(fmt, ap); log_vwrite(LOG_WARNING, fmt, ap);
free(fmt); free(fmt);
va_end(ap); va_end(ap);
} }
@ -137,7 +116,7 @@ log_warnx(const char *msg, ...)
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
log_vwrite(msg, ap); log_vwrite(LOG_WARNING, msg, ap);
va_end(ap); va_end(ap);
} }
@ -147,11 +126,9 @@ log_info(const char *msg, ...)
{ {
va_list ap; va_list ap;
if (log_level > -1) { va_start(ap, msg);
va_start(ap, msg); log_vwrite(LOG_NOTICE, msg, ap);
log_vwrite(msg, ap); va_end(ap);
va_end(ap);
}
} }
/* Log a debug message. */ /* Log a debug message. */
@ -160,11 +137,9 @@ log_debug(const char *msg, ...)
{ {
va_list ap; va_list ap;
if (log_level > 0) { va_start(ap, msg);
va_start(ap, msg); log_vwrite(LOG_INFO, msg, ap);
log_vwrite(msg, ap); va_end(ap);
va_end(ap);
}
} }
/* Log a debug message at level 2. */ /* Log a debug message at level 2. */
@ -173,11 +148,12 @@ log_debug2(const char *msg, ...)
{ {
va_list ap; va_list ap;
if (log_level > 1) { /* Not going with crazy logging on tmux */
va_start(ap, msg); #ifndef TMATE_SLAVE
log_vwrite(msg, ap); va_start(ap, msg);
va_end(ap); log_vwrite(LOG_DEBUG, msg, ap);
} va_end(ap);
#endif
} }
/* Log a critical error, with error string if necessary, and die. */ /* Log a critical error, with error string if necessary, and die. */
@ -189,11 +165,11 @@ log_vfatal(const char *msg, va_list ap)
if (errno != 0) { if (errno != 0) {
if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1) if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
exit(1); exit(1);
log_vwrite(fmt, ap); log_vwrite(LOG_CRIT, fmt, ap);
} else { } else {
if (asprintf(&fmt, "fatal: %s", msg) == -1) if (asprintf(&fmt, "fatal: %s", msg) == -1)
exit(1); exit(1);
log_vwrite(fmt, ap); log_vwrite(LOG_CRIT, fmt, ap);
} }
free(fmt); free(fmt);
@ -220,3 +196,21 @@ log_fatalx(const char *msg, ...)
va_start(ap, msg); va_start(ap, msg);
log_vfatal(msg, ap); log_vfatal(msg, ap);
} }
void printflike2 tmate_log(int level, const char *msg, ...)
{
char *fmt;
va_list ap;
if (log_settings.log_level < level)
return;
va_start(ap, msg);
if (asprintf(&fmt, "(tmate) %s", msg) < 0)
exit(1);
log_vwrite(level, fmt, ap);
va_end(ap);
free(fmt);
}

View File

@ -119,14 +119,14 @@ static void tmate_header(struct tmate_decoder *decoder,
free(client_version); free(client_version);
if (tmate_port != 22) if (tmate_settings.ssh_port != 22)
sprintf(port_arg, " -p%d", tmate_port); sprintf(port_arg, " -p%d", tmate_settings.ssh_port);
sprintf(tmp, "ssh%s ro-%s@%s", port_arg, tmate_session_token_ro, tmate_host); sprintf(tmp, "ssh%s ro-%s@%s", port_arg, tmate_session_token_ro, tmate_settings.tmate_host);
tmate_notify("Remote session read only: %s (clear your screen if you share this)", tmp); tmate_notify("Remote session read only: %s (clear your screen if you share this)", tmp);
tmate_send_env("tmate_ssh_ro", tmp); tmate_send_env("tmate_ssh_ro", tmp);
sprintf(tmp, "ssh%s %s@%s", port_arg, tmate_session_token, tmate_host); sprintf(tmp, "ssh%s %s@%s", port_arg, tmate_session_token, tmate_settings.tmate_host);
tmate_notify("Remote session: %s", tmp); tmate_notify("Remote session: %s", tmp);
tmate_send_env("tmate_ssh", tmp); tmate_send_env("tmate_ssh", tmp);

View File

@ -1,70 +0,0 @@
#include <ctype.h>
#include <unistd.h>
#include "tmate.h"
#ifdef TMATE_RECORD_REPLAY
#define READ_MAX_SIZE 1024
#define TIMER_INERVAL_USEC 1000
extern int server_shutdown;
extern void server_send_shutdown(void);
static void start_timer(struct tmate_replayer *replayer);
static void on_read_timer(evutil_socket_t fd, short what, void *arg)
{
struct tmate_replayer *replayer = arg;
char *buf;
ssize_t len;
if (replayer->log_fd < 0) {
evtimer_del(&replayer->ev_read_timer);
server_shutdown = 1;
server_send_shutdown();
return;
}
tmate_decoder_get_buffer(replayer->decoder, &buf, &len);
if (len == 0)
tmate_fatal("Decoder buffer full");
if (len > READ_MAX_SIZE)
len = READ_MAX_SIZE;
len = read(replayer->log_fd, buf, len);
if (len < 0)
tmate_fatal("cannot read from replay log file");
if (len == 0) {
tmate_info("Replay file reached EOF");
replayer->log_fd = -1;
} else {
tmate_decoder_commit(replayer->decoder, len);
}
start_timer(replayer);
}
static void start_timer(struct tmate_replayer *replayer)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = TIMER_INERVAL_USEC;
evtimer_assign(&replayer->ev_read_timer, ev_base,
on_read_timer, replayer);
evtimer_add(&replayer->ev_read_timer, &tv);
}
void tmate_replayer_init(struct tmate_replayer *replayer,
struct tmate_decoder *decoder,
int log_fd)
{
replayer->decoder = decoder;
replayer->log_fd = log_fd;
start_timer(replayer);
}
#endif

View File

@ -15,39 +15,37 @@
#include <term.h> #include <term.h>
#include <time.h> #include <time.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/syslog.h>
#include "tmate.h" #include "tmate.h"
int tmate_port = TMATE_DEFAULT_PORT;
char *tmate_host;
struct tmate_decoder *tmate_decoder; struct tmate_decoder *tmate_decoder;
struct tmate_encoder *tmate_encoder; struct tmate_encoder *tmate_encoder;
int tmux_socket_fd; int tmux_socket_fd;
const char *tmate_session_token = "main"; const char *tmate_session_token;
const char *tmate_session_token_ro = "ro-main"; const char *tmate_session_token_ro;
#ifdef TMATE_RECORD_REPLAY extern FILE *log_file;
int tmate_session_log_fd;
static void tmate_replay_slave_server(const char *replay_file);
#endif
static char *log_path; /* NULL means stderr */
static char *cmdline; static char *cmdline;
static char *cmdline_end; static char *cmdline_end;
static int dev_urandom_fd; static int dev_urandom_fd;
extern FILE *log_file;
extern int server_create_socket(void); extern int server_create_socket(void);
extern int client_connect(char *path, int start_server); extern int client_connect(char *path, int start_server);
struct tmate_settings tmate_settings = {
.keys_dir = TMATE_SSH_DEFAULT_KEYS_DIR,
.ssh_port = TMATE_SSH_DEFAULT_PORT,
.master_hostname = TMATE_DEFAULT_MASTER_HOST,
.master_port = TMATE_DEFAULT_MASTER_PORT,
.tmate_host = NULL,
.log_level = LOG_NOTICE,
.use_syslog = false,
};
static void usage(void) static void usage(void)
{ {
fprintf(stderr, "usage: tmate-slave [-k keys_dir] [-l logfile] [-p port] [-r logfile] [-h host] [-v]\n"); fprintf(stderr, "usage: tmate-slave [-k keys_dir] [-p port] [-m master_hostname] [-q master_port] [-s] [-v]\n");
}
void tmate_reopen_logfile(void)
{
log_open(debug_level, log_path);
} }
void tmate_get_random_bytes(void *buffer, ssize_t len) void tmate_get_random_bytes(void *buffer, ssize_t len)
@ -66,34 +64,29 @@ long tmate_get_random_long(void)
int main(int argc, char **argv, char **envp) int main(int argc, char **argv, char **envp)
{ {
int opt; int opt;
const char *keys_dir = "keys";
#ifdef TMATE_RECORD_REPLAY
const char *replay_file = NULL;
#endif
while ((opt = getopt(argc, argv, "p:l:vk:r:h:")) != -1) { while ((opt = getopt(argc, argv, "k:p:lvm:q:")) != -1) {
switch (opt) { switch (opt) {
case 'p': case 'p':
tmate_port = atoi(optarg); tmate_settings.ssh_port = atoi(optarg);
break;
case 'l':
log_path = optarg;
break; break;
case 'k': case 'k':
keys_dir = optarg; tmate_settings.keys_dir = xstrdup(optarg);
break;
case 's':
tmate_settings.use_syslog = true;
break; break;
case 'v': case 'v':
debug_level++; tmate_settings.log_level++;
break; break;
case 'r': case 'm':
#ifdef TMATE_RECORD_REPLAY tmate_settings.master_hostname = xstrdup(optarg);
replay_file = optarg; break;
#else case 'q':
fprintf(stderr, "Record/Replay not enabled\n"); tmate_settings.master_port = atoi(optarg);
#endif
break; break;
case 'h': case 'h':
tmate_host = xstrdup(optarg); tmate_settings.tmate_host = xstrdup(optarg);
break; break;
default: default:
usage(); usage();
@ -101,36 +94,30 @@ int main(int argc, char **argv, char **envp)
} }
} }
if (!tmate_host) { if (!tmate_settings.tmate_host) {
char hostname[255]; char hostname[255];
if (gethostname(hostname, sizeof(hostname)) < 0) if (gethostname(hostname, sizeof(hostname)) < 0)
tmate_fatal("cannot get hostname"); tmate_fatal("cannot get hostname");
tmate_host = xstrdup(hostname); tmate_settings.tmate_host = xstrdup(hostname);
} }
cmdline = *argv; cmdline = *argv;
cmdline_end = *envp; cmdline_end = *envp;
tmate_reopen_logfile(); init_logging("tmate-ssh",
tmate_settings.use_syslog, tmate_settings.log_level);
tmate_preload_trace_lib(); tmate_preload_trace_lib();
if ((dev_urandom_fd = open("/dev/urandom", O_RDONLY)) < 0) if ((dev_urandom_fd = open("/dev/urandom", O_RDONLY)) < 0)
tmate_fatal("Cannot open /dev/urandom"); tmate_fatal("Cannot open /dev/urandom");
#ifdef TMATE_RECORD_REPLAY
if (replay_file) {
tmate_replay_slave_server(replay_file);
return 0;
}
#endif
if ((mkdir(TMATE_WORKDIR, 0700) < 0 && errno != EEXIST) || if ((mkdir(TMATE_WORKDIR, 0700) < 0 && errno != EEXIST) ||
(mkdir(TMATE_WORKDIR "/sessions", 0700) < 0 && errno != EEXIST) || (mkdir(TMATE_WORKDIR "/sessions", 0700) < 0 && errno != EEXIST) ||
(mkdir(TMATE_WORKDIR "/jail", 0700) < 0 && errno != EEXIST)) (mkdir(TMATE_WORKDIR "/jail", 0700) < 0 && errno != EEXIST))
tmate_fatal("Cannot prepare session in " TMATE_WORKDIR); tmate_fatal("Cannot prepare session in " TMATE_WORKDIR);
tmate_ssh_server_main(keys_dir, tmate_port); tmate_ssh_server_main(tmate_settings.keys_dir, tmate_settings.ssh_port);
return 0; return 0;
} }
@ -296,32 +283,6 @@ static void setup_ncurse(int fd, const char *name)
tmate_fatal("Cannot setup terminal"); tmate_fatal("Cannot setup terminal");
} }
#ifdef TMATE_RECORD_REPLAY
static void tmate_replay_slave_server(const char *replay_file)
{
struct tmate_decoder decoder;
struct tmate_replayer replayer;
tmate_debug("Replaying slave server with %s", replay_file);
tmux_socket_fd = server_create_socket();
if (tmux_socket_fd < 0)
tmate_fatal("Cannot create to the tmux socket");
tmate_session_log_fd = open(replay_file, O_RDONLY);
if (tmate_session_log_fd < 0)
tmate_fatal("cannot open session-dump.log");
ev_base = osdep_event_init();
tmate_decoder_init(&decoder);
tmate_replayer_init(&replayer, &decoder, tmate_session_log_fd);
tmux_server_init(IDENTIFY_UTF8 | IDENTIFY_256COLOURS);
/* never reached */
}
#endif
static void tmate_spawn_slave_server(struct tmate_ssh_client *client) static void tmate_spawn_slave_server(struct tmate_ssh_client *client)
{ {
char *token; char *token;
@ -339,7 +300,6 @@ static void tmate_spawn_slave_server(struct tmate_ssh_client *client)
tmate_debug("Spawning slave server for %s at %s (%s)", tmate_debug("Spawning slave server for %s at %s (%s)",
client->username, client->ip_address, client->pubkey); client->username, client->ip_address, client->pubkey);
tmux_socket_fd = server_create_socket(); tmux_socket_fd = server_create_socket();
if (tmux_socket_fd < 0) if (tmux_socket_fd < 0)
tmate_fatal("Cannot create to the tmux socket"); tmate_fatal("Cannot create to the tmux socket");
@ -354,14 +314,7 @@ static void tmate_spawn_slave_server(struct tmate_ssh_client *client)
close_fds_except((int[]){tmux_socket_fd, close_fds_except((int[]){tmux_socket_fd,
ssh_get_fd(client->session), ssh_get_fd(client->session),
fileno(log_file)}, 3); log_file ? fileno(log_file) : -1}, 3);
#ifdef TMATE_RECORD_REPLAY
tmate_session_log_fd = open("session-log.log",
O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (tmate_session_log_fd < 0)
tmate_fatal("cannot open session-dump.log");
#endif
jail(); jail();
@ -395,7 +348,7 @@ static void tmate_spawn_slave_client(struct tmate_ssh_client *client)
if (validate_token(token) < 0) { if (validate_token(token) < 0) {
ssh_echo(client, BAD_TOKEN_ERROR_STR); ssh_echo(client, BAD_TOKEN_ERROR_STR);
tmate_fatal("Bad token"); tmate_fatal("Invalid token");
} }
set_session_token(client, token); set_session_token(client, token);
@ -405,7 +358,7 @@ static void tmate_spawn_slave_client(struct tmate_ssh_client *client)
tmux_socket_fd = client_connect(socket_path, 0); tmux_socket_fd = client_connect(socket_path, 0);
if (tmux_socket_fd < 0) { if (tmux_socket_fd < 0) {
random_sleep(); /* for timing attacks */ random_sleep(); /* for making timing attacks harder */
ssh_echo(client, EXPIRED_TOKEN_ERROR_STR); ssh_echo(client, EXPIRED_TOKEN_ERROR_STR);
tmate_fatal("Expired token"); tmate_fatal("Expired token");
} }
@ -436,7 +389,7 @@ static void tmate_spawn_slave_client(struct tmate_ssh_client *client)
setup_ncurse(slave_pty, "screen-256color"); setup_ncurse(slave_pty, "screen-256color");
close_fds_except((int[]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, close_fds_except((int[]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
tmux_socket_fd, ssh_get_fd(client->session), tmux_socket_fd, ssh_get_fd(client->session),
client->pty, fileno(log_file)}, 7); client->pty, log_file ? fileno(log_file) : -1}, 7);
jail(); jail();
ev_base = osdep_event_init(); ev_base = osdep_event_init();

View File

@ -12,25 +12,6 @@ extern void server_send_shutdown(void);
server_send_shutdown(); \ server_send_shutdown(); \
} while(0) } while(0)
#ifdef TMATE_RECORD_REPLAY
static void record_session_data(const char *buf, size_t len)
{
ssize_t ret;
while (len > 0) {
ret = write(tmate_session_log_fd, buf, len);
if (ret < 0)
tmate_fatal("cannot save recording of the session");
buf += ret;
len -= ret;
}
}
#else
static inline void record_session_data(const char *buf, size_t len)
{}
#endif
static void consume_channel(struct tmate_ssh_client *client) static void consume_channel(struct tmate_ssh_client *client)
{ {
char *buf; char *buf;
@ -56,8 +37,6 @@ static void consume_channel(struct tmate_ssh_client *client)
if (len == 0) if (len == 0)
break; break;
record_session_data(buf, len);
tmate_decoder_commit(client->decoder, len); tmate_decoder_commit(client->decoder, len);
} }
} }

View File

@ -129,6 +129,8 @@ static void client_bootstrap(struct tmate_ssh_client *client)
ssh_session session = client->session; ssh_session session = client->session;
ssh_message msg; ssh_message msg;
tmate_notice("Bootstrapping ssh client ip=%s", client->ip_address);
/* new process group, we don't want to die with our parent (upstart) */ /* new process group, we don't want to die with our parent (upstart) */
setpgid(0, 0); setpgid(0, 0);
@ -149,7 +151,8 @@ static void client_bootstrap(struct tmate_ssh_client *client)
tmate_debug("Exchanging DH keys"); tmate_debug("Exchanging DH keys");
if (ssh_handle_key_exchange(session) < 0) if (ssh_handle_key_exchange(session) < 0)
tmate_fatal("Error doing the key exchange"); tmate_fatal("Error doing the key exchange: %s",
ssh_get_error(session));
mainloop = ssh_event_new(); mainloop = ssh_event_new();
ssh_event_add_session(mainloop, session); ssh_event_add_session(mainloop, session);
@ -189,18 +192,12 @@ static void handle_sigsegv(void)
tmate_fatal("CRASHED"); tmate_fatal("CRASHED");
} }
static void handle_sigusr1(void)
{
tmate_reopen_logfile();
}
static void signal_handler(int sig) static void signal_handler(int sig)
{ {
switch (sig) { switch (sig) {
case SIGCHLD: handle_sigchld(); break; case SIGCHLD: handle_sigchld(); break;
case SIGALRM: handle_sigalrm(); break; case SIGALRM: handle_sigalrm(); break;
case SIGSEGV: handle_sigsegv(); break; case SIGSEGV: handle_sigsegv(); break;
case SIGUSR1: handle_sigusr1(); break;
} }
} }
@ -209,7 +206,6 @@ static void setup_signals(void)
signal(SIGCHLD, signal_handler); signal(SIGCHLD, signal_handler);
signal(SIGALRM, signal_handler); signal(SIGALRM, signal_handler);
signal(SIGSEGV, signal_handler); signal(SIGSEGV, signal_handler);
signal(SIGUSR1, signal_handler);
} }
static pid_t namespace_fork(void) static pid_t namespace_fork(void)
@ -260,7 +256,6 @@ static ssh_bind prepare_ssh(const char *keys_dir, int port)
ssh_bind bind; ssh_bind bind;
char buffer[PATH_MAX]; char buffer[PATH_MAX];
int verbosity = SSH_LOG_NOLOG; int verbosity = SSH_LOG_NOLOG;
//int verbosity = SSH_LOG_PACKET;
ssh_set_log_callback(ssh_log_function); ssh_set_log_callback(ssh_log_function);
@ -272,16 +267,16 @@ static ssh_bind prepare_ssh(const char *keys_dir, int port)
ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BANNER, TMATE_SSH_BANNER); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_BANNER, TMATE_SSH_BANNER);
ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY, &verbosity); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_LOG_VERBOSITY, &verbosity);
sprintf(buffer, "%s/ssh_host_dsa_key", keys_dir);
ssh_bind_options_set(bind, SSH_BIND_OPTIONS_DSAKEY, buffer);
sprintf(buffer, "%s/ssh_host_rsa_key", keys_dir); sprintf(buffer, "%s/ssh_host_rsa_key", keys_dir);
ssh_bind_options_set(bind, SSH_BIND_OPTIONS_RSAKEY, buffer); ssh_bind_options_set(bind, SSH_BIND_OPTIONS_RSAKEY, buffer);
sprintf(buffer, "%s/ssh_host_ecdsa_key", keys_dir);
ssh_bind_options_set(bind, SSH_BIND_OPTIONS_ECDSAKEY, buffer);
if (ssh_bind_listen(bind) < 0) if (ssh_bind_listen(bind) < 0)
tmate_fatal("Error listening to socket: %s\n", ssh_get_error(bind)); tmate_fatal("Error listening to socket: %s\n", ssh_get_error(bind));
tmate_info("Accepting connections on %d", port); tmate_notice("Accepting connections on %d", port);
return bind; return bind;
} }
@ -321,7 +316,7 @@ void tmate_ssh_server_main(const char *keys_dir, int port)
ssh_free(client->session); ssh_free(client->session);
} else { } else {
ssh_bind_free(bind); ssh_bind_free(bind);
tmate_session_token = "........................."; tmate_session_token = "init";
client_bootstrap(client); client_bootstrap(client);
} }
} }

56
tmate.h
View File

@ -1,6 +1,7 @@
#ifndef TMATE_H #ifndef TMATE_H
#define TMATE_H #define TMATE_H
#include <sys/syslog.h>
#include <sys/types.h> #include <sys/types.h>
#include <msgpack.h> #include <msgpack.h>
#include <libssh/libssh.h> #include <libssh/libssh.h>
@ -8,15 +9,18 @@
#include "tmux.h" #include "tmux.h"
// #define TMATE_RECORD_REPLAY /* useful to debug crashes */ extern void init_logging(const char *program_name, bool use_syslog, int log_level);
extern void printflike2 tmate_log(int level, const char *msg, ...);
#define tmate_debug(str, ...) log_debug("[tmate] " str, ##__VA_ARGS__) #define tmate_debug(str, ...) tmate_log(LOG_DEBUG, str, ##__VA_ARGS__)
#define tmate_info(str, ...) log_info("[tmate] " str, ##__VA_ARGS__) #define tmate_info(str, ...) tmate_log(LOG_INFO, str, ##__VA_ARGS__)
#define tmate_fatal(str, ...) \ #define tmate_notice(str, ...) tmate_log(LOG_NOTICE, str, ##__VA_ARGS__)
do { \ #define tmate_warn(str, ...) tmate_log(LOG_WARNING, str, ##__VA_ARGS__)
log_info("[tmate] FATAL " str, ##__VA_ARGS__); \ #define tmate_fatal(str, ...) \
exit(-1); \ ({ \
} while (0) tmate_log(LOG_CRIT, "fatal: " str, ##__VA_ARGS__); \
exit(1); \
})
/* tmate-encoder.c */ /* tmate-encoder.c */
@ -84,22 +88,6 @@ extern void tmate_decoder_get_buffer(struct tmate_decoder *decoder,
char **buf, size_t *len); char **buf, size_t *len);
extern void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len); extern void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len);
#ifdef TMATE_RECORD_REPLAY
/* tmate-replayer.c */
struct tmate_replayer {
struct tmate_decoder *decoder;
int log_fd;
struct event ev_read_timer;
};
extern void tmate_replayer_init(struct tmate_replayer *replayer,
struct tmate_decoder *decoder,
int log_fd);
#endif
/* tmate-ssh-client.c */ /* tmate-ssh-client.c */
#define TMATE_ROLE_SERVER 1 #define TMATE_ROLE_SERVER 1
@ -153,12 +141,28 @@ extern void tmate_ssh_server_main(const char *keys_dir, int port);
/* tmate-slave.c */ /* tmate-slave.c */
struct tmate_settings {
const char *keys_dir;
int ssh_port;
const char *master_hostname;
int master_port;
const char *tmate_host;
int log_level;
bool use_syslog;
};
extern struct tmate_settings tmate_settings;
#ifdef DEVENV #ifdef DEVENV
#define TMATE_DEFAULT_PORT 2200 #define TMATE_SSH_DEFAULT_PORT 2200
#else #else
#define TMATE_DEFAULT_PORT 22 #define TMATE_SSH_DEFAULT_PORT 22
#endif #endif
#define TMATE_SSH_DEFAULT_KEYS_DIR "keys"
#define TMATE_DEFAULT_MASTER_HOST NULL
#define TMATE_DEFAULT_MASTER_PORT 7000
#define TMATE_TOKEN_LEN 25 #define TMATE_TOKEN_LEN 25
#define TMATE_WORKDIR "/tmp/tmate" #define TMATE_WORKDIR "/tmp/tmate"
#define TMATE_JAIL_USER "nobody" #define TMATE_JAIL_USER "nobody"