TNT/include/ssh_server.h
m1ngsama b5f9a17290 refactor: extract bootstrap module (PR2-M4)
Move the per-connection SSH bootstrap pipeline -- key exchange, auth,
channel open + PTY/shell-or-exec request, and the hand-off into a
client_t -- out of ssh_server.c into a dedicated module.

Migrated to bootstrap.{c,h}:
- session_context_t (now private to bootstrap.c)
- accepted_session_t (declared in bootstrap.h, the IPC envelope from
  the accept loop into the bootstrap thread)
- TNT_ACCESS_TOKEN handling: g_access_token + bootstrap_init()
- constant_time_strcmp (auth-only utility)
- bootstrap_peer_ip (peer IP read from libssh fd)
- auth_password / auth_none / auth_pubkey
- destroy_session_context, cleanup_failed_session
- channel_open_request_session, channel_pty_request,
  channel_pty_window_change, channel_shell_request, channel_exec_request
- setup_session_channel_callbacks
- bootstrap_run (formerly bootstrap_client_session, the pthread entry)

Stayed in ssh_server.c:
- accept loop in ssh_server_start (now calls bootstrap_peer_ip and
  pthread_create(bootstrap_run))
- ssh_server_init (now calls ratelimit_init() + bootstrap_init() +
  reads only g_idle_timeout / TNT_BIND_ADDR / TNT_SSH_LOG_LEVEL)
- client_send/printf/addref/release, notify_mentions
- client_channel_window_change/eof/close (post-bootstrap, target client_t)
- client_install_channel_callbacks (renamed from
  install_client_channel_callbacks, now non-static and exposed via
  ssh_server.h so bootstrap.c can install them on the new client_t)
- read_username, handle_key, client_handle_session (will move to
  input.c in PR2-M5)
- setup_host_key, ssh_server_start_time

Two helpers also lifted: sanitize_terminal_size moved to common.c (used
by the bootstrap PTY callback and the post-bootstrap window-change
callback), and is_valid_username already lived there from M2.

ssh_server.c shrinks from 1513 to 1026 lines (-487).
Behaviour is preserved: implementations are byte-for-byte the same.
2026-05-17 09:47:28 +08:00

77 lines
2.5 KiB
C

#ifndef SSH_SERVER_H
#define SSH_SERVER_H
#include "common.h"
#include "chat_room.h"
#include <arpa/inet.h>
#include <libssh/libssh.h>
#include <libssh/server.h>
/* Client connection structure */
typedef struct client {
ssh_session session; /* SSH session */
ssh_channel channel; /* SSH channel */
char username[MAX_USERNAME_LEN];
char client_ip[INET6_ADDRSTRLEN];
_Atomic int width;
_Atomic int height;
client_mode_t mode;
help_lang_t help_lang;
int scroll_pos;
int help_scroll_pos;
bool show_help;
char command_input[256];
char command_history[16][256];
int command_history_count;
int command_history_pos;
char command_output[2048];
char exec_command[MAX_EXEC_COMMAND_LEN];
char ssh_login[MAX_USERNAME_LEN];
time_t connect_time;
time_t last_active;
atomic_bool redraw_pending;
bool mute_joins;
pthread_t thread;
atomic_bool connected;
int ref_count; /* Reference count for safe cleanup */
pthread_mutex_t ref_lock; /* Lock for ref_count */
pthread_mutex_t io_lock; /* Serialize SSH channel writes */
struct ssh_channel_callbacks_struct *channel_cb;
} client_t;
/* Initialize SSH server */
int ssh_server_init(int port);
/* Start SSH server (blocking) */
int ssh_server_start(int listen_fd);
/* Handle client session */
void* client_handle_session(void *arg);
/* Send data to client */
int client_send(client_t *client, const char *data, size_t len);
/* Send formatted string to client */
int client_printf(client_t *client, const char *fmt, ...);
/* Reference counting helpers */
void client_addref(client_t *client);
void client_release(client_t *client);
/* Install the post-bootstrap channel callbacks (window-change, eof, close)
* that target this client_t. Caller MUST have already added one
* client_addref() to keep the client alive across in-flight callback
* invocations; the matching client_release() happens during cleanup in
* client_handle_session(). Returns 0 on success, -1 on failure (in which
* case the caller still owns both refs and must release them). */
int client_install_channel_callbacks(client_t *client);
/* Bell-notify any clients whose @username appears in the broadcast content,
* skipping the sender. Defined in ssh_server.c (will move to a dedicated
* client.c during PR2-M6). */
void notify_mentions(const char *content, const client_t *sender);
/* Read-only accessor for the server start time (used by exec stats). */
time_t ssh_server_start_time(void);
#endif /* SSH_SERVER_H */