### Create tmate-slave Init Script (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Generates a SysVinit script for managing the tmate-slave service, including start, stop, restart, and status functionalities. It allows configuration via /etc/default/tmate-slave. ```bash cat << 'EOF' > /etc/init.d/tmate-slave #!/bin/sh ### BEGIN INIT INFO # Provides: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO APP_NAME=tmate-slave APP_CONF_DIR="/" APP_USER="$APP_NAME" APP_CMD="/usr/local/bin/$APP_NAME" APP_ARG_PORT="22" APP_ARG_HOST="" APP_ARG_KEYSDIR="/etc/tmate-slave/keys" if [ -r /etc/default/$APP_NAME ]; then . /etc/default/$APP_NAME fi APP_ARGS="-k $APP_ARG_KEYSDIR -p $APP_ARG_PORT " [ -z $APP_ARG_HOST ] || APP_ARGS="$APP_ARGS -h $APP_ARG_HOST" name=`basename $0` pid_file="/var/run/$name.pid" stdout_log="/var/log/$name.log" stderr_log="/var/log/$name.err" get_pid() { cat "$pid_file" } is_running() { [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1 } case "$1" in start) if is_running; then echo "Already started" else echo "Starting $name" cd "$APP_CONF_DIR" su - "$APP_USER" -c "$APP_CMD $APP_ARGS" >> "$stdout_log" 2>> "$stderr_log" & echo $! > "$pid_file" if ! is_running; then echo "Unable to start, see $stdout_log and $stderr_log" exit 1 fi fi ;; stop) if is_running; then echo -n "Stopping $name.." kill `get_pid` for i in {1..10} do if ! is_running; then break fi echo -n "." sleep 1 done echo if is_running; then echo "Not stopped; may still be shutting down or shutdown may have failed" exit 1 else echo "Stopped" if [ -f "$pid_file" ]; then rm "$pid_file" fi fi else echo "Not running" fi ;; restart) $0 stop if is_running; then echo "Unable to stop, will not attempt to start" exit 1 fi $0 start ;; status) if is_running; then echo "Running" else echo "Stopped" exit 1 fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 EOF chmod +x /etc/init.d/tmate-slave ``` -------------------------------- ### Install and Compile tmate-slave (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Clones the tmate-slave repository, builds it from source, and installs it. Also sets kernel capabilities for running tmate-slave as an unprivileged user. ```bash git clone https://github.com/nviennot/tmate-slave.git cd tmate-slave/ ./autogen.sh && \ ./configure && \ make && \ make install setcap CAP_SETUID,CAP_SYS_ADMIN,CAP_SYS_CHROOT,CAP_SETGID=+ep /usr/local/bin/tmate-slave ``` -------------------------------- ### Start tmate-slave Service (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Starts the tmate-slave service using the system's service management tool. It's recommended to use a different port if SSH is already running on the default port. ```bash sudo service tmate-slave start ``` -------------------------------- ### Manage libevent Version (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Checks for libevent installation, removes older versions if found, downloads libevent2, compiles, and installs it. Includes creating a symbolic link for 64-bit systems. ```bash # rpm -qa | grep libevent # yum remove -y libevent libevent-devel libevent-headers wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz tar xf libevent-2.0.21-stable.tar.gz cd libevent-2.0.21-stable ./configure && \ make && \ make install cd .. ln -s /usr/local/lib/libevent-2.0.so.5 /usr/lib64/libevent-2.0.so.5 ``` -------------------------------- ### Setup Log Files for tmate-slave Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Create log files for tmate-slave and set the correct ownership. The log files are created in /var/log/ and owned by the tmate-slave user. ```bash touch /var/log/tmate-slave.{log,err} chown tmate-slave /var/log/tmate-slave.{log,err} ``` -------------------------------- ### Install Development Tools and tmate Dependencies (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Installs essential development tools and packages required for tmate using yum. This includes group install for development tools and then specific packages for tmate functionality. ```bash # yum groupinstall -y 'Development Tools' # yum install -y git kernel-devel zlib-devel openssl-devel ncurses-devel cmake ruby libssh-devel wget ``` -------------------------------- ### Configure tmate-slave User, Keys, and Logs (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Sets up the 'tmate-slave' user, creates and secures SSH keys for the service, and configures log files with correct ownership. ```bash useradd tmate-slave ./create_keys.sh install -d -m 0700 -o tmate-slave -g root /etc/tmate-slave/keys keys mv keys/* /etc/tmate-slave/keys sudo chown -R tmate-slave /etc/tmate-slave touch /var/log/tmate-slave.{log,err} chown tmate-slave /var/log/tmate-slave.{log,err} ``` -------------------------------- ### Setup tmate-slave User Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Add a system user specifically for running tmate-slave. This user will own the process and related files. ```bash useradd tmate-slave ``` -------------------------------- ### Create init.d Script for tmate-slave Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Create an init.d script to manage the tmate-slave daemon. This script allows starting, stopping, restarting, and checking the status of the tmate-slave service. ```bash cat << 'EOF' > /etc/init.d/tmate-slave #!/bin/sh ### BEGIN INIT INFO # Provides: # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO APP_NAME=tmate-slave APP_CONF_DIR="/" APP_USER="$APP_NAME" APP_CMD="/usr/local/bin/$APP_NAME" APP_ARG_PORT="22" APP_ARG_HOST="" APP_ARG_KEYSDIR="/etc/tmate-slave/keys" if [ -r /etc/default/$APP_NAME ]; then . /etc/default/$APP_NAME fi APP_ARGS="-k $APP_ARG_KEYSDIR -p $APP_ARG_PORT " [ -z $APP_ARG_HOST ] || APP_ARGS="$APP_ARGS -h $APP_ARG_HOST" name=`basename $0` pid_file="/var/run/$name.pid" stdout_log="/var/log/$name.log" stderr_log="/var/log/$name.err" get_pid() { cat "$pid_file" } is_running() { [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1 } case "$1" in start) if is_running; then echo "Already started" else echo "Starting $name" cd "$APP_CONF_DIR" #su - "$APP_USER" -c "$APP_CMD $APP_ARGS" >> "$stdout_log" 2>> "$stderr_log" & $APP_CMD $APP_ARGS >> $stdout_log 2>> $stderr_log & echo $! > "$pid_file" if ! is_running; then echo "Unable to start, see $stdout_log and $stderr_log" exit 1 fi fi ;; stop) if is_running; then echo -n "Stopping $name.." kill `get_pid` for i in {1..10} do if ! is_running; then break fi echo -n "." sleep 1 done echo if is_running; then echo "Not stopped; may still be shutting down or shutdown may have failed" exit 1 else echo "Stopped" if [ -f "$pid_file" ]; then rm "$pid_file" fi fi else echo "Not running" fi ;; restart) $0 stop if is_running; then echo "Unable to stop, will not attempt to start" exit 1 fi $0 start ;; status) if is_running; then echo "Running" else echo "Stopped" exit 1 fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 EOF chmod +x /etc/init.d/tmate-slave ``` -------------------------------- ### Compile and Install tmate-slave Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Clone the tmate-slave repository, configure, compile, and install the software. This involves using autogen.sh, configure, make, and make install commands. ```bash git clone https://github.com/nviennot/tmate-slave.git cd tmate-slave/ ./autogen.sh && \ ./configure && \ make && \ make install ``` -------------------------------- ### Configure tmate-slave Default Settings (Bash) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Sets default environment variables for the tmate-slave service, specifically for the port and host arguments, which can be overridden in the init script. ```bash cat << 'EOF' > /etc/default/tmate-slave export APP_ARG_PORT="" export APP_ARG_HOST="" EOF ``` -------------------------------- ### Configure and Start tmate SSH Server (C) Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Initializes and starts the tmate SSH server, setting up configurations such as SSH port, hostnames, and key directories. It also prepares necessary working directories for session management. This function is crucial for the server's operation and requires valid paths and ports for successful initialization. ```c #include "tmate.h" int main(int argc, char **argv, char **envp) { int opt; // Configure server settings while ((opt = getopt(argc, argv, "Ab:h:k:p:q:w:z:xv")) != -1) { switch (opt) { case 'A': tmate_settings->authorized_keys_only = true; break; case 'b': tmate_settings->bind_addr = xstrdup(optarg); break; case 'h': tmate_settings->tmate_host = xstrdup(optarg); break; case 'k': tmate_settings->keys_dir = xstrdup(optarg); break; case 'p': tmate_settings->ssh_port = atoi(optarg); break; case 'q': tmate_settings->ssh_port_advertized = atoi(optarg); break; case 'w': tmate_settings->websocket_hostname = xstrdup(optarg); break; case 'z': tmate_settings->websocket_port = atoi(optarg); break; case 'x': tmate_settings->use_proxy_protocol = true; break; case 'v': tmate_settings->log_level++; break; } } init_logging(tmate_settings->log_level); setup_locale(); tmate_init_rand(); // Create working directories if ((mkdir(TMATE_WORKDIR, 0700) < 0 && errno != EEXIST) || (mkdir(TMATE_WORKDIR "/sessions", 0700) < 0 && errno != EEXIST) || (mkdir(TMATE_WORKDIR "/jail", 0700) < 0 && errno != EEXIST)) tmate_fatal("Cannot prepare session in " TMATE_WORKDIR); // Start SSH server main loop tmate_ssh_server_main(tmate_session, tmate_settings->keys_dir, tmate_settings->bind_addr, tmate_settings->ssh_port); return 0; } // Example command line invocation: // tmate-ssh-server -k /path/to/keys -p 2200 -h tmate.example.com -w ws.example.com -z 4002 -vv // This starts the server on port 2200, advertises tmate.example.com as hostname, // connects to WebSocket server at ws.example.com:4002, and enables verbose logging ``` -------------------------------- ### Configure tmate Client Connection (Shell) Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-6.6 Configures the tmate client to connect to a specific tmate-ssh-server. This involves setting the server host, port, and SSH key fingerprints in the `~/.tmate.conf` file. ```shell set -g tmate-server-host "[your server FQDN]" set -g tmate-server-port [server port] set -g tmate-server-dsa-fingerprint "dsa fingerprint" set -g tmate-server-rsa-fingerprint "rsa fingerprint" set -g tmate-server-ecdsa-fingerprint "ecdsa fingerprint" #set -g tmate-identity "" # Can be specified to use a different SSH key ``` -------------------------------- ### Install Development Tools on CentOS 7 Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Install the necessary development tools on CentOS 7 using yum. This group includes tools required for compiling software. ```bash yum groupinstall -y 'Development Tools' ``` -------------------------------- ### Create and Configure Keys for tmate-slave Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Create SSH keys for tmate-slave and set the correct ownership and permissions. The keys are stored in /etc/tmate-slave/keys and owned by the tmate-slave user. ```bash ./create_keys.sh install -d -m 0700 -o tmate-slave -g root /etc/tmate-slave/keys keys/ mv keys/* /etc/tmate-slave/keys sudo chown -R tmate-slave /etc/tmate-slave ``` -------------------------------- ### Configure tmate Client Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Configure the tmate client to connect to the tmate-slave server by creating a .tmate.conf file in the user's home directory. This file specifies the server host, port, and fingerprints. ```bash cat << EOF > $HOME/.tmate.conf set -g tmate-server-host "[your server FQDN]" set -g tmate-server-port [server port] set -g tmate-server-dsa-fingerprint "dsa fingerprint" set -g tmate-server-rsa-fingerprint "rsa fingerprint" set -g tmate-server-ecdsa-fingerprint "ecdsa fingerprint" #set -g tmate-identity "" # Can be specified to use a different SSH key EOF ``` -------------------------------- ### Install tmate-slave Dependencies on CentOS 7 Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Install the dependencies required to compile tmate-slave on CentOS 7. These dependencies include git, kernel-devel, zlib-devel, openssl-devel, ncurses-devel, cmake, ruby, libssh-devel, wget, msgpack-devel, and libevent-devel. ```bash yum install -y git kernel-devel zlib-devel openssl-devel ncurses-devel cmake ruby libssh-devel wget msgpack-devel libevent-devel ``` -------------------------------- ### Set Capabilities for tmate-slave Source: https://github.com/tmate-io/tmate-ssh-server/wiki/How-to-Install-tmate-slave-on-CentOS-7 Set specific capabilities for the tmate-slave executable to allow certain operations. This command grants CAP_SETUID, CAP_SYS_ADMIN, CAP_SYS_CHROOT, and CAP_SETGID capabilities. ```bash setcap CAP_SETUID,CAP_SYS_ADMIN,CAP_SYS_CHROOT,CAP_SETGID=+ep /usr/local/bin/tmate-slave ``` -------------------------------- ### VT105 Graphics Initialization Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt This entry describes the control sequence for starting VT105 graphics mode on a VT125 terminal. It utilizes a specific escape sequence to enable graphical capabilities. ```text Pt = Start VT105 graphics on a VT125 ``` -------------------------------- ### ANSI Escape Sequences for Terminal Control Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt This snippet demonstrates common ANSI escape sequences used for controlling terminal behavior. These sequences are fundamental for cursor movement, screen clearing, and text manipulation in terminal applications. They typically start with ESC (1B hex) followed by '[' and then parameters and a command character. ```text ESC [ 10 @ - Insert CHaracter ESC [ A - Cursor Up ESC [ B - Cursor Down ESC [ C - Cursor Forward ESC [ D - Cursor Backward ESC [ H - Cursor Position (Home) ESC [ 24;80 H - Cursor to Row 24, Column 80 ESC [ J - Erase in Display (from cursor to end) ESC [ 2 J - Erase entire display ESC [ K - Erase in Line (from cursor to end) ESC [ 2 K - Erase entire current line ESC [ L - Insert Line ESC [ M - Delete Line ESC [ P - Delete Character ``` -------------------------------- ### Initialize WebSocket Buffers and Callbacks in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Initializes the WebSocket communication for a given tmate session. It creates a bufferevent for the WebSocket socket, sets up error handling callbacks, and initializes encoders and decoders for data transmission. This function depends on the libevent library and tmate's internal data structures. ```c // Initialize WebSocket buffers and callbacks void tmate_init_websocket(struct tmate_session *session, on_websocket_error_cb on_websocket_error) { if (!tmate_has_websocket()) return; session->websocket_sx = -1; session->websocket_sy = -1; // Create bufferevent for WebSocket socket session->bev_websocket = bufferevent_socket_new(session->ev_base, session->websocket_fd, BEV_OPT_CLOSE_ON_FREE); if (!session->bev_websocket) tmate_fatal("Cannot setup socket bufferevent"); session->on_websocket_error = on_websocket_error ?: on_websocket_event_default; bufferevent_setcb(session->bev_websocket, on_websocket_read, NULL, on_websocket_event, session); bufferevent_enable(session->bev_websocket, EV_READ | EV_WRITE); tmate_encoder_init(&session->websocket_encoder, on_websocket_encoder_write, session); tmate_decoder_init(&session->websocket_decoder, on_websocket_decoder_read, session); } ``` -------------------------------- ### Initialize Message Pack Encoder in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Initializes a tmate encoder structure, setting up the write callback, user data, buffer, msgpack version, and packer. It prepares the encoder for serializing data using Message Pack format. ```c void tmate_encoder_init(struct tmate_encoder *encoder, tmate_encoder_write_cb *callback, void *userdata) { encoder->ready_callback = callback; encoder->userdata = userdata; encoder->buffer = evbuffer_new(); encoder->mpac_version = 5; // msgpack version msgpack_packer_init(&encoder->pk, encoder->buffer, evbuffer_write_msgpack); encoder->ev_active = false; } ``` -------------------------------- ### Initialize Message Pack Decoder in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Initializes a tmate decoder structure, setting up the reader, user data, and the Message Pack unpacker. It configures the decoder to handle incoming messages up to a maximum size. ```c void tmate_decoder_init(struct tmate_decoder *decoder, tmate_decoder_reader *reader, void *userdata) { decoder->reader = reader; decoder->userdata = userdata; msgpack_unpacker_init(&decoder->unpacker, TMATE_MAX_MESSAGE_SIZE); } ``` -------------------------------- ### Connect to WebSocket Server in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Establishes a TCP connection to a specified WebSocket server hostname and port. It handles socket creation, host resolution, connection establishment, and sets socket options for TCP_NODELAY and non-blocking mode. Errors during these operations are fatal. ```c // Connect to WebSocket server int tmate_connect_to_websocket(void) { const char *hostname = tmate_settings->websocket_hostname; int port = tmate_settings->websocket_port; int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) tmate_fatal("Cannot create socket"); struct hostent *host = gethostbyname(hostname); if (!host) tmate_fatal("Cannot resolve %s", hostname); struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = host->h_addrtype; memcpy(&servaddr.sin_addr, host->h_addr, host->h_length); servaddr.sin_port = htons(port); if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) tmate_fatal("Cannot connect to websocket server at %s:%d", hostname, port); int flag = 1; if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) < 0) tmate_fatal("Can't set websocket server socket to TCP_NODELAY"); if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) tmate_fatal("Can't set websocket server socket to non-blocking"); tmate_debug("Connected to websocket server at %s:%d", hostname, port); return sockfd; } ``` -------------------------------- ### Send Exec Command via WebSocket in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Sends an execution command to the WebSocket server for a given tmate session. It checks if WebSocket is available and then packs the command along with session details like username, IP address, and public key. ```c void tmate_websocket_exec(struct tmate_session *session, const char *command) { struct tmate_ssh_client *client = &session->ssh_client; if (!tmate_has_websocket()) return; pack(array, 5); pack(int, TMATE_CTL_EXEC); pack(string, client->username); pack(string, client->ip_address); pack_string_or_nil(client->pubkey); pack(string, command); } ``` -------------------------------- ### Page Navigation Commands Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt Commands for navigating through multiple pages of terminal memory. 'NP' (Next Page) moves to the subsequent page, while 'PP' (Previous Page) moves to the preceding page. ```text [2U = Scroll forward 2 pages [1V = Scroll backward 1 page ``` -------------------------------- ### SSH Public Key Authentication Callback Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Handles the SSH public key authentication callback. It verifies the provided public key against authorized keys configured for the session. Dependencies include libssh, tmate's internal validation functions, and socket communication utilities. It takes the session, username, public key, signature state, and user data as input, returning SSH_AUTH_SUCCESS or SSH_AUTH_DENIED. ```c static int auth_pubkey_cb(__unused ssh_session session, const char *user, ssh_key pubkey, char signature_state, void *userdata) { struct tmate_ssh_client *client = userdata; switch (signature_state) { case SSH_PUBLICKEY_STATE_VALID: client->username = xstrdup(user); 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"); char *pubkey64; xasprintf(&pubkey64, "%s %s", key_type, b64_key); free(b64_key); // Verify against authorized keys if configured if (!would_tmate_session_allow_auth(user, pubkey64)) { free(pubkey64); return SSH_AUTH_DENIED; } client->pubkey = pubkey64; return SSH_AUTH_SUCCESS; case SSH_PUBLICKEY_STATE_NONE: return SSH_AUTH_SUCCESS; default: return SSH_AUTH_DENIED; } } // Check authentication against session's authorized keys bool would_tmate_session_allow_auth(const char *token, const char *pubkey) { int sock_fd = -1; int ret = true; if (tmate_validate_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); 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; // Send authentication request to session 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; out: if (sock_fd != -1) close(sock_fd); return ret; } // Configure authorized keys in tmux configuration: // set -g @tmate-authorized-keys "" // set -g @tmate-set "authorized_keys=ssh-rsa AAAAB3NzaC1yc2E... user@host" ``` -------------------------------- ### Dispatch WebSocket Messages in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Handles incoming messages from the WebSocket connection for a tmate session. It decodes commands and dispatches them to appropriate handlers, including message forwarding, snapshot requests, keystroke processing, terminal resizing, execution response handling, and session renaming. ```c static void tmate_dispatch_websocket_message(struct tmate_session *session, struct tmate_unpacker *uk) { int cmd = unpack_int(uk); switch (cmd) { case TMATE_CTL_DEAMON_FWD_MSG: // Forward message to tmate daemon if (uk->argc != 1) tmate_decoder_error(); tmate_send_mc_obj(&uk->argv[0]); break; case TMATE_CTL_REQUEST_SNAPSHOT: // Create and send session snapshot ctl_daemon_request_snapshot(session, uk); break; case TMATE_CTL_PANE_KEYS: // Handle keystroke input int pane_id = unpack_int(uk); char *str = unpack_string(uk); for (int i = 0; str[i]; i++) tmate_client_pane_key(pane_id, str[i]); free(str); break; case TMATE_CTL_RESIZE: // Handle terminal resize session->websocket_sx = (u_int)unpack_int(uk); session->websocket_sy = (u_int)unpack_int(uk); recalculate_sizes(); break; case TMATE_CTL_EXEC_RESPONSE: // Handle command execution response int exit_code = unpack_int(uk); char *message = unpack_string(uk); tmate_dump_exec_response(session, exit_code, message); free(message); break; case TMATE_CTL_RENAME_SESSION: // Update session token char *stoken = unpack_string(uk); char *stoken_ro = unpack_string(uk); set_session_token(session, stoken); free(stoken); free(stoken_ro); break; default: tmate_info("Bad websocket server message type: %d", cmd); } } ``` -------------------------------- ### Send Session Header to WebSocket Server in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Formats and sends a session header message to the WebSocket server. This message includes control protocol version, client IP address, public key, session tokens, SSH connection string, and client version information. It uses tmate's internal packing functions. ```c // Send session header to WebSocket server void tmate_send_websocket_header(struct tmate_session *session) { if (!tmate_has_websocket()) return; pack(array, 9); pack(int, TMATE_CTL_HEADER); pack(int, CONTROL_PROTOCOL_VERSION); pack(string, session->ssh_client.ip_address); pack_string_or_nil(session->ssh_client.pubkey); pack(string, session->session_token); pack(string, session->session_token_ro); char *ssh_cmd_fmt = get_ssh_conn_string("%s"); pack(string, ssh_cmd_fmt); free(ssh_cmd_fmt); pack(string, session->client_version); pack(int, session->client_protocol_version); } ``` -------------------------------- ### Session Token and Socket Path Management Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Manages session tokens and generates Unix socket paths. This function is crucial for identifying and locating active tmate sessions. It involves string manipulation for path creation and updating process names for better visibility. Dependencies include string manipulation functions and tmate's internal logging and process management utilities. ```c // Set session token and configure process name void set_session_token(struct tmate_session *session, const char *token) { session->session_token = xstrdup(token); socket_path = get_socket_path(token); // Create obfuscated version for logging xasprintf((char **)&session->obfuscated_session_token, "%.4s...", session->session_token); // Update process name for visibility size_t size = cmdline_end - cmdline; memset(cmdline, 0, size); snprintf(cmdline, size-1, "tmate-ssh-server [%s] %s %s", tmate_session->obfuscated_session_token, session->ssh_client.role == TMATE_ROLE_DAEMON ? "(daemon)" : "(pty client)", session->ssh_client.ip_address); char *log_prefix; xasprintf(&log_prefix, "[%s] ", session->obfuscated_session_token); set_log_prefix(log_prefix); free(log_prefix); } // Generate socket path from session token char *get_socket_path(const char *_token) { char *path; char *token = xstrdup(_token); // Replace problematic characters for (char *c = token; *c; c++) { if (*c == '/' || *c == '.') *c = '='; } // Create path in sessions directory xasprintf(&path, TMATE_WORKDIR "/sessions/%s", token); free(token); return path; } // Example usage flow: // Client connects with username "abc123xyz" // Server creates socket at /tmp/tmate/sessions/abc123xyz // Process name becomes: tmate-ssh-server [abc1...] (daemon) 192.168.1.100 // All logs prefixed with [abc1...] ``` -------------------------------- ### ANSI Character Attributes and Colors Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt This snippet defines ANSI escape codes for setting foreground and background colors, as well as other character attributes like bold, dim, underline, blink, and negative image. These codes are fundamental for text formatting in terminals. ```text [30m = Write with black, [40m = Set background to black (GIGI) [31m = Write with red, [41m = Set background to red [32m = Write with green, [42m = Set background to green [33m = Write with yellow, [43m = Set background to yellow [34m = Write with blue, [44m = Set background to blue [35m = Write with magenta, [45m = Set background to magenta [36m = Write with cyan, [46m = Set background to cyan [37m = Write with white, [47m = Set background to white [22m = Cancel bold or dim attribute only (VT220) [24m = Cancel underline attribute only (VT220) [25m = Cancel fast or slow blink attribute only (VT220) [27m = Cancel negative image attribute only (VT220) ``` -------------------------------- ### DECREQTPARM - Request Terminal Parameters Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt DECREQTPARM is a command to request various terminal parameters from the device. The response format specifies details like bit mode, baud rate, and other operational settings. ```text [3;5;2;64;64;1;0x = Report, 7 bit Even, 1200 baud, 1200 baud ``` -------------------------------- ### VT100 Keyboard Input Sequences Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt This section details the escape sequences sent by specific keys on the VT100 keyboard, including cursor keys, PF keys, and the numeric keypad. This is essential for capturing user input accurately. ```text [A Sent by the up-cursor key (alternately ESC O A) [B Sent by the down-cursor key (alternately ESC O B) [C Sent by the right-cursor key (alternately ESC O C) [D Sent by the left-cursor key (alternately ESC O D) OP PF1 key sends ESC O P OQ PF2 key sends ESC O Q OR PF3 key sends ESC O R OS PF4 key sends ESC O S [c Request for the terminal to identify itself [?1;0c VT100 with memory for 24 by 80, inverse video character attribute [?1;2c VT100 capable of 132 column mode, with bold+blink+underline+inverse ESC = Set numeric keypad to applications mode ESC > Set numeric keypad to numbers mode OA Up-cursor key sends ESC O A OB Down-cursor key sends ESC O B OC Right-cursor key sends ESC O C OD Left-cursor key sends ESC O D OM ENTER key sends ESC O M Ol COMMA on keypad sends ESC O l Om MINUS on keypad sends ESC O m Op ZERO on keypad sends ESC O p ``` -------------------------------- ### DECSLPP - Set Physical Lines Per Page Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt DECSLPP allows the terminal to be configured with the number of physical lines per page. This is relevant for printers or displays simulating physical pages, affecting layout and pagination. ```text [66t = Paper has 66 lines (11 inches at 6 per inch) ``` -------------------------------- ### Device Status Report (DSR) and Printer Status Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt This section covers Device Status Report (DSR) commands, used to query the terminal's status or request cursor position. It also includes commands for requesting printer status and checking user-defined key lock status. ```text [0n = Terminal is ready, no malfunctions detected [1n = Terminal is busy, retry later [2n = Terminal is busy, it will send DSR when ready [3n = Malfunction, please try again [4n = Malfunction, terminal will send DSR when ready [5n = Command to terminal to report its status [6n = Command to terminal requesting cursor position (CPR) [?15n = Command to terminal requesting printer status, returns [?10n = OK, [?11n = not OK, [?13n = no printer. [?25n = "Are User Defined Keys Locked?" (VT220) ``` -------------------------------- ### Repeat Previous Displayable Character (REP) Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt Repeats the previous character a specified number of times. This is useful for drawing lines or filling areas with a repeated character. ```text [80b = Repeat character 80 times ``` -------------------------------- ### Cursor Vertical Tab (CVT) and Cursor Back Tab (CBT) Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt Controls movement to vertical and horizontal tab stops. CVT moves to a specified vertical tab stop, while CBT moves backward to a horizontal tab stop. ```text [2Y = Move forward to 2nd following vertical tab stop [3Z = Move backwards to 3rd previous horizontal tab stop ``` -------------------------------- ### DECKEYS - Special Function Keys Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt DECEKEYS sequences are sent by special function keys on DEC terminals. This snippet lists mappings for keys like FIND, INSERT, REMOVE, SELECT, PREV, NEXT, and function keys F6-F20, as well as ESC, BS, LF, and HELP. ```text [1~=FIND, [2~=INSERT, [3~=REMOVE, [4~=SELECT, [5~=PREV, [6~=NEXT [17~=F6...[34~=F20 ([23~=ESC,[24~=BS,[25~=LF,[28~=HELP,[29~=DO) ``` -------------------------------- ### Define Area Qualification (DAQ) Sequences Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt These sequences define the characteristics of input areas on the screen. They specify how data is accepted, transmitted, and formatted within a defined field, supporting features like protection, numeric input, and justification. ```text [0o = Accept all input, transmit on request [1o = Protected and guarded, accept no input, do not transmit [2o = Accept any printing character in this field [3o = Numeric only field [4o = Alphabetic (A-Z and a-z) only [5o = Right justify in area [3;6o = Zero fill in area [7o = Set horizontal tab stop, this is the start of the field [8o = Protected and unguarded, accept no input, do transmit [9o = Space fill in area ``` -------------------------------- ### VT100 Graphic Size and Spacing Control Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt These escape sequences allow for modifications to graphic size and spacing increments, influencing how text and graphics are rendered on the terminal. This includes font selection and justification. ```text [4 @ = Move everything over 4 columns, 4 new columns at right [2 A = Move everything over 2 columns, 2 new columns at left [110;50 B = Make 110% high, 50% wide [120 C = Make characters 120 decipoints (1/6 inch) high [0;23 D = Make primary font be registered font #23 [36 E = Define a thin space to be 36 decipoints (1/20 inch) [0 E = No justification [1 E = Fill, bringing words up from next line if necessary [2 E = Interword spacing, adjust spaces between words [3 E = Letter spacing, adjust width of each letter [4 E = Use hyphenation [5 E = Flush left margin [6 E = Center following text between margins [7 E = Flush right margin [8 E = Italian form (underscore instead of hyphen) [120;72 G = 6 per inch vertical, 10 per inch horizontal [0 H = Flush left [1 H = Flush left and fill with leader [2 H = Center [3 H = Center and fill with leader [4 H = Flush right [5 H = Flush right and fill with leader ``` -------------------------------- ### VT100 Cursor Movement and Screen Clearing Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt These control sequences are used for basic cursor manipulation and screen clearing operations. They are fundamental for navigating and modifying the display in VT100 emulation. ```text [A Move cursor up one row [B Move cursor down one row [C Move cursor forward one column [D Move cursor backward one column [H Home to row 1 column 1 [J Clear from current position to bottom of screen [K Clear from current position to end of line [24;80H Position to line 24 column 80 [0J Erase from current position to bottom of screen inclusive [1J Erase from top of screen to current position inclusive [2J Erase entire screen [0K Erase from current position to end of line inclusive [1K Erase from beginning of line to current position inclusive [2K Erase entire line ``` -------------------------------- ### DECLL - Load LEDs Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt DECLL sequences are used to control the status LEDs on DEC terminals. This allows applications to provide visual feedback to the user about the terminal's state or specific functions. ```text [0q = Turn off all, [?1;4q turns on L1 and L4, etc [154;155;157q = VT100 goes bonkers [2;23!q = Partial screen dump from GIGI to graphics printer [0"q = DECSCA Select Character Attributes off [1"q = DECSCA - designate set as non-erasable [2"q = DECSCA - designate set as erasable ``` -------------------------------- ### DECSHORP - Set Horizontal Pitch Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt This sequence configures the horizontal pitch (characters per inch) for LAxxx printers. It affects the spacing and density of printed characters. ```text [1w = 10 characters per inch, [2w = 12 characters per inch [0w=10, [3w=13.2, [4w=16.5, [5w=5, [6w=6, [7w=6.6, [8w=8.25 ``` -------------------------------- ### DECSTBM - Set Top and Bottom Margins Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt DECSTBM is used to define the scrolling region of the terminal. By setting top and bottom margins, specific areas of the screen can be designated for scrolling, while other areas remain static. ```text [4;20r = Set top margin at line 4 and bottom at line 20 ``` -------------------------------- ### DECSTR - Soft Terminal Reset Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt The DECSTR (Soft Terminal Reset) sequence reinitializes the terminal to a default state without a full power cycle. This is useful for recovering from unexpected states or configurations. ```text [!p = Soft Terminal Reset ``` -------------------------------- ### Scrolling Commands - Up and Down Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt Controls the scrolling behavior of the terminal screen. 'SU' (Scroll Up) moves content upwards, introducing new lines at the bottom. 'SD' (Scroll Down) moves content downwards, inserting new lines at the top. ```text [3S = Move everything up 3 lines, bring in 3 new lines [4T = Scroll down 4, bring previous lines back into view ``` -------------------------------- ### Notify WebSocket of Client Join in C Source: https://context7.com/tmate-io/tmate-ssh-server/llms.txt Notifies the WebSocket server when a new client joins the tmate session. It sends client ID, IP address, public key, and read-only status to the server. This function also sets a flag indicating that the join event has been notified. It only proceeds if WebSocket is enabled. ```c // Notify WebSocket of client connections void tmate_notify_client_join(__unused struct tmate_session *session, struct client *c) { tmate_info("Client joined (cid=%d)", c->id); if (!tmate_has_websocket()) return; c->flags |= CLIENT_TMATE_NOTIFIED_JOIN; pack(array, 5); pack(int, TMATE_CTL_CLIENT_JOIN); pack(int, c->id); pack(string, c->ip_address); pack_string_or_nil(c->pubkey); pack(boolean, c->readonly); } ``` -------------------------------- ### VT100 Scrolling Region and Editing Functions Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt These sequences define the scrolling region and are used for full-screen editing operations like inserting and deleting lines. They enable more advanced terminal interactions. ```text [12;24r Set scrolling region to lines 12 thru 24. ``` -------------------------------- ### Set Mode (SM) - General Terminal Modes Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt Configures various operational modes of the terminal. These modes affect how the terminal interprets control sequences and displays characters. ```text [0h = Error, this command is ignored [1h = GATM - Guarded Area Transmit Mode, send all (VT132) [2h = KAM - Keyboard Action Mode, disable keyboard input [3h = CRM - Control Representation Mode, show all control chars [4h = IRM - Insertion/Replacement Mode, set insert mode (VT102) [5h = SRTM - Status Report Transfer Mode, report after DCS [6h = ERM - ERasure Mode, erase protected and unprotected [7h = VEM - Vertical Editing Mode, IL/DL affect previous lines [10h = HEM - Horizontal Editing mode, ICH/DCH/IRM go backwards [11h = PUM - Positioning Unit Mode, use decipoints for HVP/etc [12h = SRM - Send Receive Mode, transmit without local echo [13h = FEAM - Format Effector Action Mode, FE's are stored [14h = FETM - Format Effector Transfer Mode, send only if stored [15h = MATM - Multiple Area Transfer Mode, send all areas [16h = TTM - Transmit Termination Mode, send scrolling region [17h = SATM - Send Area Transmit Mode, send entire buffer [18h = TSM - Tabulation Stop Mode, lines are independent [19h = EBM - Editing Boundry Mode, all of memory affected [20h = LNM - Linefeed Newline Mode, LF interpreted as CR LF ``` -------------------------------- ### VT100 Character Attributes Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt These sequences control the visual attributes of characters, such as normal display, inverse video, and other formatting options. They are crucial for displaying text with different styles. ```text [0m Clear attributes to normal characters [7m Add the inverse video attribute to succeeding characters [0;7m Set character attributes to inverse video only ``` -------------------------------- ### Vertical Position Absolute (VPA) Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt Moves the cursor to an absolute vertical position on the screen. The position can be specified in decipoints from the top margin or as a line number. ```text [90d = Move to 90 decipoints (1/8 inch) from top margin [10d = Move to line 10 if before that else line 10 next page ``` -------------------------------- ### SL - Scroll Left Source: https://github.com/tmate-io/tmate-ssh-server/blob/master/tools/ansicode.txt The SL (Scroll Left) control sequence shifts the content of the display buffer to the left. This is a basic operation for horizontal scrolling or manipulating display content. ```text 40 @ ```