0
0
Fork 0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2025-03-14 20:32:46 +00:00
tmate-io_tmate-ssh-server/tmate.h
ebardie d7334ee4c3
Add '-A' option to enforce use of authorized_keys ()
Add an option to the server to force clients to always set an
authorized_keys file. Without it it is all too easy to forget and leave
the connexions accessible to anyone with the session name.

Co-authored-by: Jonathan Sambrook <jonathan.sambrook@codethink.co.uk>
2023-06-02 10:18:46 -04:00

313 lines
9.2 KiB
C

#ifndef TMATE_H
#define TMATE_H
#include <sys/types.h>
#include <msgpack.h>
#include <libssh/libssh.h>
#include <libssh/callbacks.h>
#include <event.h>
#include <time.h>
#include "tmux.h"
struct tmate_session;
/* log.c */
#define tmate_debug(...) log_emit(LOG_DEBUG, __VA_ARGS__)
#define tmate_info(...) log_emit(LOG_INFO, __VA_ARGS__)
#define tmate_fatal(...) fatalx( __VA_ARGS__)
#define tmate_fatal_quiet(...) ({tmate_debug(__VA_ARGS__); exit(1);})
/* tmate-auth-keys.c */
extern void tmate_hook_set_option_auth(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 */
typedef void tmate_encoder_write_cb(void *userdata, struct evbuffer *buffer);
struct tmate_encoder {
msgpack_packer pk;
int mpac_version;
tmate_encoder_write_cb *ready_callback;
void *userdata;
struct evbuffer *buffer;
struct event ev_buffer;
bool ev_active;
};
extern void tmate_encoder_init(struct tmate_encoder *encoder,
tmate_encoder_write_cb *callback,
void *userdata);
/* These functions deal with dual v4/v5 support through mpac_version */
extern void msgpack_pack_string(msgpack_packer *pk, const char *str);
extern void msgpack_pack_boolean(msgpack_packer *pk, bool value);
extern int _msgpack_pack_object(msgpack_packer *pk, msgpack_object d);
#define msgpack_pack_object _msgpack_pack_object
#define _pack(enc, what, ...) msgpack_pack_##what(&(enc)->pk, ##__VA_ARGS__)
struct tmate_unpacker;
struct tmate_decoder;
typedef void tmate_decoder_reader(void *userdata, struct tmate_unpacker *uk);
struct tmate_decoder {
struct msgpack_unpacker unpacker;
tmate_decoder_reader *reader;
void *userdata;
};
extern void tmate_decoder_init(struct tmate_decoder *decoder, tmate_decoder_reader *reader, void *userdata);
extern void tmate_decoder_get_buffer(struct tmate_decoder *decoder, char **buf, size_t *len);
extern void tmate_decoder_commit(struct tmate_decoder *decoder, size_t len);
struct tmate_unpacker {
int argc;
msgpack_object *argv;
};
extern void init_unpacker(struct tmate_unpacker *uk, msgpack_object obj);
extern void tmate_decoder_error(void);
extern int64_t unpack_int(struct tmate_unpacker *uk);
extern bool unpack_bool(struct tmate_unpacker *uk);
extern void unpack_buffer(struct tmate_unpacker *uk, const char **buf, size_t *len);
extern char *unpack_string(struct tmate_unpacker *uk);
extern void unpack_array(struct tmate_unpacker *uk, struct tmate_unpacker *nested);
extern msgpack_object_type unpack_peek_type(struct tmate_unpacker *uk);
#define unpack_each(nested_uk, tmp_uk, uk) \
for (unpack_array(uk, tmp_uk); \
(tmp_uk)->argc > 0 && (init_unpacker(nested_uk, (tmp_uk)->argv[0]), 1); \
(tmp_uk)->argv++, (tmp_uk)->argc--)
/* tmate-daemon-encoder.c */
extern void printflike(1, 2) tmate_notify(const char *fmt, ...);
extern void printflike(2, 3) tmate_notify_later(int timeout, const char *fmt, ...);
extern void tmate_client_resize(u_int sx, u_int sy);
extern void tmate_client_legacy_pane_key(int pane_id, int key);
extern void tmate_client_pane_key(int pane_id, key_code key);
extern void tmate_client_cmd_str(int client_id, const char *cmd);
extern void tmate_client_cmd_args(int client_id, int argc, const char **argv);
extern void tmate_client_cmd(int client_id, struct cmd *cmd);
extern void tmate_client_set_active_pane(int client_id, int win_idx, int pane_id);
extern int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd);
extern void tmate_set_env(const char *name, const char *value);
extern void tmate_send_client_ready(void);
extern void tmate_send_mc_obj(msgpack_object *obj);
/* tmate-daemon-legacy.c */
extern void tmate_translate_legacy_key(int pane_id, key_code key);
/* tmate-daemon-decoder.c */
#define TMATE_HLIMIT 2000
#define TMATE_PANE_ACTIVE 1
#define TMATE_MAX_MESSAGE_SIZE (17*1024)
#define TMATE_MAX_PANES 1000
extern char *tmate_left_status, *tmate_right_status;
extern void tmate_dispatch_daemon_message(struct tmate_session *session,
struct tmate_unpacker *uk);
/* tmate-ssh-daemon.c */
#define TMATE_KEYFRAME_INTERVAL_SEC 10
#define TMATE_KEYFRAME_MAX_SIZE 1024*1024
extern void tmate_spawn_daemon(struct tmate_session *session);
extern void tmate_hook_set_option(const char *name, const char *val);
/* tmate-ssh-exec.c */
extern void tmate_spawn_exec(struct tmate_session *session);
extern void tmate_dump_exec_response(struct tmate_session *session,
int exit_code, const char *message);
/* tmate-ssh-client-pty.c */
extern void tmate_spawn_pty_client(struct tmate_session *session);
extern int tmate_validate_session_token(const char *token);
/* tmate-ssh-server.c */
#define TMATE_SSH_BANNER "tmate"
#define TMATE_SSH_KEEPALIVE_SEC 300
#define TMATE_ROLE_DAEMON 1
#define TMATE_ROLE_PTY_CLIENT 2
#define TMATE_ROLE_EXEC 3
struct tmate_ssh_client;
typedef void ssh_client_latency_cb(void *userdata, int latency_ms);
extern char *get_ssh_conn_string(const char *session_token);
extern void start_keepalive_timer(struct tmate_ssh_client *client, int timeout_ms);
struct tmate_ssh_client {
char ip_address[64];
ssh_session session;
ssh_channel channel;
/*
* We need to store the entire callback struct because
* libssh stores the userdata within the cb struct...
*/
struct ssh_channel_callbacks_struct channel_cb;
int role;
char *username;
char *pubkey;
char *exec_command;
struct winsize winsize_pty;
struct event ev_ssh;
struct event ev_keepalive_timer;
int keepalive_interval_ms;
};
extern void tmate_ssh_server_main(struct tmate_session *session,
const char *keys_dir, const char *bind_addr, int port);
/* tmate-main.c */
#ifdef DEVENV
#define TMATE_SSH_DEFAULT_PORT 2200
#else
#define TMATE_SSH_DEFAULT_PORT 22
#endif
#define TMATE_SSH_GRACE_PERIOD 20
#define TMATE_SSH_DEFAULT_KEYS_DIR "keys"
#define TMATE_DEFAULT_WEBSOCKET_PORT 4002
#define TMATE_TOKEN_LEN 25
#define TMATE_WORKDIR "/tmp/tmate"
#define TMATE_JAIL_USER "nobody"
struct tmate_settings {
const char *keys_dir;
const char *authorized_keys_path;
bool authorized_keys_only;
int ssh_port;
int ssh_port_advertized;
const char *websocket_hostname;
int websocket_port;
const char *tmate_host;
const char *bind_addr;
int log_level;
bool use_proxy_protocol;
};
extern struct tmate_settings *tmate_settings;
typedef void on_websocket_error_cb(struct tmate_session *session, short events);
struct tmate_session {
struct event_base *ev_base;
struct tmate_ssh_client ssh_client;
int tmux_socket_fd;
/* only for role deamon */
ssh_key *authorized_keys; /* array with NULL as last element */
const char *session_token;
const char *session_token_ro;
const char *obfuscated_session_token; /* for logging purposes */
struct tmate_encoder daemon_encoder;
struct tmate_decoder daemon_decoder;
const char *client_version;
int client_protocol_version;
struct event ev_notify_timer;
bool fin_received;
int websocket_fd;
struct bufferevent *bev_websocket;
struct tmate_encoder websocket_encoder;
struct tmate_decoder websocket_decoder;
u_int websocket_sx, websocket_sy;
on_websocket_error_cb *on_websocket_error;
/* only for role client-pty */
int pty;
struct event ev_pty;
bool readonly;
/* only for role-exec */
bool response_received;
bool response_status;
const char *response_message;
};
extern struct tmate_session *tmate_session;
extern void tmate_get_random_bytes(void *buffer, ssize_t len);
extern long tmate_get_random_long(void);
extern void request_server_termination(void);
extern char *get_socket_path(const char *_token);
extern void set_session_token(struct tmate_session *session, const char *token);
extern void close_fds_except(int *fd_to_preserve, int num_fds);
extern void get_in_jail(void);
/* tmate-rand.c */
#define RS_BUF_SIZE 256
struct random_stream {
char bytes[RS_BUF_SIZE];
off_t pos;
};
extern void tmate_init_rand(void);
extern void tmate_get_random_bytes(void *buffer, ssize_t len);
extern long tmate_get_random_long(void);
extern void random_stream_init(struct random_stream *rs);
extern char *random_stream_get(struct random_stream *rs, size_t count);
extern void setup_ncurse(int fd, const char *name);
/* tmate-websocket.c */
extern void tmate_websocket_exec(struct tmate_session *session, const char *command);
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_send_websocket_daemon_msg(struct tmate_session *session,
struct tmate_unpacker *uk);
extern void tmate_send_websocket_header(struct tmate_session *session);
extern void tmate_init_websocket(struct tmate_session *session,
on_websocket_error_cb on_websocket_error);
extern int tmate_connect_to_websocket(void);
static inline bool tmate_has_websocket(void)
{
return !!tmate_settings->websocket_hostname;
}
/* tmate-debug.c */
extern void tmate_preload_trace_lib(void);
extern void tmate_print_stack_trace(void);
extern void tmate_catch_sigsegv(void);
/* tmux.c */
extern void tmux_server_init(void);
/* server.c */
extern int server_create_socket(void);
/* log.c */
extern FILE *log_file;
/* client.c */
extern void client_signal(int sig);
extern int client_connect(struct event_base *base, const char *path, int start_server);
#endif