mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:34:39 +08:00
21 KiB
21 KiB
Changelog
Unreleased
Added
- Documented the stable SSH exec interface contract, including exit statuses
and JSON field shapes for package tests, scripts, and future
tntctlwork. - Added a public security policy, supported-version guidance, and GitHub issue templates for bug reports and feature requests.
- Added
tntctl, a thin local wrapper around the documented SSH exec interface for health, stats, users, tail, post, help, and exit commands. - Added explicit server configuration flags for bind address, public host, connection limits, rate limiting, idle timeout, and SSH log verbosity.
- Added a configurable soak test that keeps an interactive session open while repeatedly checking health, stats, users, reconnects, and post/tail behavior.
- Added a two-user TUI lifecycle regression test and user-lifecycle notes for the main onboarding, chat, help, history, search, private-message, nickname, action-message, and exit paths.
- Added a VHS tape draft for recording the core TNT terminal-chat experience.
Changed
make install-systemdnow rewrites the installed unit'sExecStartto match the selectedPREFIX/BINDIR, so package builds that install to/usrproduce a unit pointing at/usr/bin/tnt.- Release preflight now checks the staged systemd unit path, and strict release checks also require a clean tree, tag-at-HEAD, changelog release section, and non-placeholder maintainer metadata.
- CI and release workflows now use explicit least-privilege repository permissions.
- The release guide now documents SemVer expectations, manual release review, smoke testing, and rollback steps.
- Package installs now include
tntctland its man page alongsidetnt. - SSH exec commands longer than the command buffer are now rejected with a usage error instead of being truncated and executed.
- SSH exec
postnow persists the message before broadcasting or returningposted, so persistence failures are not visible as successful room events. - Mention and private-message bell notifications are now queued on the target client and flushed by that client's own session loop, so slow SSH writes do not block the sender's message path.
- Interactive client writes now pass through a bounded per-client outbox and flush against the remote SSH window from that client's session loop. Exec sessions still write synchronously to preserve script output ordering.
- Private-message inbox access now uses its own mutex instead of sharing the SSH channel write lock, reducing unrelated contention on slow clients.
- Client writes now check the SSH channel's remote window before writing and mark the client disconnected when the window is closed, avoiding the most direct slow-reader blocking path.
make release-checkcan now run the soak test withRUN_SOAK=1, keeping longer runtime checks opt-in for local release validation.- Room capacity and mention notification bookkeeping now follow
TNT_MAX_CONNECTIONSinstead of a hidden fixed 64-client array limit. - Updated the roadmap to reflect completed
tntctl, stable exec contract, and monitoring-interface work, leaving the remaining daemon naming and runtime queue work explicit. - Strict release preflight now builds and installs from the local
vX.Y.Ztag source archive, catching untracked files that would be missing from a GitHub source release. - Release documentation now creates the local tag before strict release checks, matching the strict gate's tag-at-HEAD requirement.
- Split UI-language parsing from localized text lookup:
src/i18n.cnow owns locale/code parsing, whilesrc/i18n_text.cowns the table-driven text catalog with coverage checks for every message ID. - Kept command placeholders stable across localized output: Chinese help and
usage text now uses ASCII metavariables such as
<user>and<message>. - Standardized user-facing
:msg/:inboxterminology around "private message" / "私信" instead of mixing it with "whisper" wording. - Kept localized startup CLI syntax stable by using
用法: tnt [options]instead of localizing the[options]metavariable. - Moved SSH exec help rows into an
exec_catalogmodule so command metadata no longer lives as one large translated blob inside the shared i18n table. - Refreshed contributor and development guidance so new commands are added
through
command_catalog,exec_catalog, andi18n_textinstead of stalessh_server.c/ inline-strcmpinstructions. exec_catalognow owns SSH exec command matching as well as help metadata, reducing duplicate command knowledge insrc/exec.c.- Replaced hard-coded
chat.m1ng.spaceexamples withchat.example.comso public documentation does not imply a specific production host. - Moved SSH exec usage text and argument-shape checks into
exec_catalog, sosrc/exec.cno longer duplicates--jsonand required-message validation. - Moved interactive command usage text and first-pass argument-shape checks
into
command_catalog, so known commands with bad arguments now show usage instead of unknown-command guidance. - Renamed the internal language state from help-oriented names to
UI-language names (
ui_lang_t,client->ui_lang, andi18n_*_ui_lang) so future i18n work has a correctly named seam. - Command names, aliases, help summaries, concise-manual command rows, and
unknown-command suggestions now share a dedicated
command_catalogmodule. - COMMAND-mode output is now a small scrollable pager with
j/k, page movement,g/G, andq/Esc close controls, so long:lastand:searchresults are readable instead of being cut off by the terminal height. - Collapsed the interactive help surface around a concise Unix-style
:helpmanual and the?full key reference;:supportis no longer a user-facing command. - First-use hints and unknown-command guidance now point users to
:helpinstead of the removed support entry. - The concise manual module is now named
manual_text, and the redundant interactive:commandsentrypoint was removed. - The concise
:helpmanual now stays within one command-output screen so it does not truncate on normal terminal sizes. - Language selection is limited to stable codes (
en,zh) and locale-shaped environment values; natural-language labels are not accepted as command arguments. - Full-screen help now uses
lto cycle the UI language through the i18n module instead of hard-coding one key per language. - Language parsing, language-code output, and help-language cycling now share one internal language registry.
- Removed the unused
MODE_HELPenum value and refreshed development-guide module descriptions for the split between language parsing and text lookup. i18n_textnow indexes localized strings byUI_LANG_*instead of storing English/Chinese as hard-coded struct fields.command_catalognow uses the shared localized-string helper for help, manual, and usage text instead of per-field English/Chinese members.exec_catalognow uses the same localized-string helper for exec help summaries.- Startup CLI help and option error formats now use the shared localized-string helper and English fallback path.
- The concise
:helpmanual text now uses the shared localized-string helper around the command-catalog rows. - The full-screen key reference now uses the shared localized-string helper around the command-catalog rows.
- SSH exec help headers and usage prefixes now use the shared localized-string helper and English fallback path.
- Documented i18n and user-facing text rules for English-first source text, stable command syntax, concise help copy, and translation-only localization.
- Rewrote the quick setup guide as a concise English-first user lifecycle document with a short Chinese notes section.
- The shared UI text catalog now uses the same localized-string initializer as the smaller text modules, avoiding GCC missing-braces warnings.
1.0.1 - 2026-05-24 - Release candidate hardening
Added
- Added a first i18n boundary:
TNT_LANG/ locale detection now chooses the default interactive UI language (enorzh) for username prompts, status hints, help output, and:support. - Added
:lang <en|zh>so users can switch the interactive UI language for their current session. - COMMAND-mode
:help, unknown-command guidance, language command output, and continuation prompts now follow the session UI language. - The full-screen help title and footer now follow the session UI language, with UTF-8-aware title padding for Chinese.
- Common COMMAND-mode outputs now respect the session language, including
:usersheaders and:mute-joinsstate text. - Command-output and MOTD screen chrome now use the session UI language.
- Common command usage errors now stay in the session language, and bare
:search,:msg, and:nickshow usage instead of falling through to unknown-command guidance. - Command output text for common interactive commands is now centralized in the i18n table instead of being scattered through command flow logic.
- TUI title-bar status labels, including online count, mute marker, and help hint, now follow the session UI language.
- Join, leave, and nickname-change system messages now use a dedicated
system_messagemodule, follow the sender's session language, and keep:mute-joinsfiltering compatible with both Chinese and English logs. - The interactive welcome screen now follows the selected UI language, including the narrow-terminal fallback.
- Full-screen help and COMMAND-mode help now live in a dedicated
help_textmodule, keeping large bilingual help copy out of TUI and command flow code. - Session language, unknown-command, suggestion, and continuation prompts now use the shared i18n table instead of inline command-flow conditionals.
- Interactive and exec support guide copy now lives in a dedicated
support_textmodule, with focused language-selection unit coverage. - Exec-mode help, usage errors, unknown-command feedback, and post validation
messages now follow
TNT_LANGwhile preserving stable machine-readable command output. - Startup CLI help and option errors now live in a dedicated
cli_textmodule and followTNT_LANG/ locale for English and Chinese users. - Idle-timeout disconnect notices now follow the session UI language.
Changed
make testnow fails on integration-test regressions; constrained local environments can usemake test-advisoryfor the previous advisory behavior.- Removed the duplicate
deploy.ymlCI workflow so automated checks stay focused on CI while production deployment remains manual. - Fixed the per-IP connection-rate limit to allow the configured number of
attempts before blocking, added unit coverage, and exposed
make connection-limit-testfor the black-box limit regression test. - Security feature checks now use isolated ports and temporary state
directories, so they no longer require
timeout/gtimeoutor writehost_key/messages.loginto the test directory. - Added
make security-testandmake ci-testso local runs can use the same full verification path as GitHub Actions. - Anonymous access checks now use isolated state, wait for real SSH health,
avoid external
timeouthelpers, and run throughmake anonymous-access-testas part ofmake ci-test. - Stress testing now uses isolated state, waits for real SSH health, avoids
external
timeouthelpers, and is available throughmake stress-test. - Basic integration tests now wait for real SSH
healthresponses instead of sleeping for a fixed startup delay. - Connection-limit tests now use shared SSH health readiness checks for both concurrent-session and connection-rate scenarios.
- CI memory-leak smoke checks now use an isolated state directory, wait for
real SSH readiness, and clean up the exact server PID instead of
pkill. - CI memory-leak smoke checks now pre-generate the host key and use a longer valgrind readiness window, avoiding false failures during slow startup.
- Language parsing now tolerates surrounding whitespace and accepts the
englishalias, improvingTNT_LANGand:langergonomics. - Refreshed the development guide's command/keybinding instructions so they
point at the current modular
commands,exec,i18n, and help text files. - Refreshed README and quick-reference module maps to match the current
cli_text,help_text,support_text, i18n, exec, and rate-limit modules. - NORMAL mode now opens at the latest visible messages instead of the oldest
in-memory message. Use
k/PageUp to browse older history andG/End to return to the latest messages. - NORMAL mode status now shows the visible message range and points users to
G latestwhen new messages arrive while they are browsing. - NORMAL mode now keeps following the latest messages while the view is pinned to the bottom; scrolling upward switches into history browsing.
- NORMAL mode now accepts arrow keys, PageUp/PageDown, and Home/End in addition to the existing Vim-style keys.
- Message viewport and scroll-state rules now live in a focused
history_viewmodule instead of being split across input and rendering code. - Added unit coverage for
history_viewscroll boundaries, live-follow state, and date-divider-aware latest windows. - Status/input line rendering now lives in a focused
tui_statusmodule, keeping the main TUI renderer closer to layout orchestration. - Added
:support/supportquick guides so interactive users and SSH exec clients can discover common actions and troubleshooting paths in-product. - The GitHub workflow formerly named deploy now runs CI only; production deployment remains a manual operator action.
- Command output rendering now truncates ANSI-styled UTF-8 text without counting escape sequences as visible width or cutting color codes.
- Host-key generation now uses the non-deprecated libssh PKI API on libssh 0.12+ while keeping compatibility with older libssh releases.
- INSERT mode now shows a lightweight first-use hint for sending, browsing,
and
:support. :supportis now task-oriented around common user goals, and mistyped commands suggest the nearest known command when possible.- Added a local
make release-checkpreflight for release/package validation without tagging, publishing, or deploying. - CI now installs
expecton Ubuntu so interactive integration tests run instead of being skipped, and runsmake release-checkon every push/PR. - The tag-triggered release workflow now builds on native x64/arm64 runners, verifies artifact architecture, emits one checksum file, and creates a draft release for manual review instead of publishing immediately.
- The one-line installer now downloads
checksums.txt, verifies the selected binary before installation, and fails fast on missing release assets. - Added a Debian packaging metadata draft for the future Ubuntu PPA path, with
lightweight validation in
make release-check. - Added an Arch
.SRCINFOdraft and AUR maintainer notes, with version/package checks inmake release-check. - Added Homebrew tap maintainer notes, and expanded
make release-checkto validate the formula class andlibsshdependency.
2026-05-18 - Interactive input polish
Added
- Bracketed paste handling keeps multi-line pasted text in the input buffer until the user presses Enter, then sends it as one message.
- Input and paste overflow now rings the terminal bell when the 1023-byte message limit is reached.
- Added an interactive
expectregression test for basic TTY input, bracketed paste, and overlong paste capping. - Added the exec-mode regression test to the main
make testpath.
Fixed
- SSH exec clients now survive stdin EOF long enough to flush stdout, exit
status, EOF, and channel close. This fixes non-interactive commands such as
ssh localhost healthandssh user@host post "message".
2026-05-16 - Internal cleanup
Fixed
message_load()now holdsg_message_file_lockfor the duration of the read. Previously:last [N]could race withmessage_save()and observe a half-written line.constant_time_strcmp()accumulates the length difference insize_tinstead ofunsigned char. The old code lost the length-mismatch signal when the two lengths differed by a multiple of 256.
Changed
buffer_appendf()andbuffer_append_bytes()moved tocommon.c; the two identical copies inssh_server.candtui.chave been removed.- Removed
TODO.md(both items completed) anddocs/README.old(superseded by the rootREADME.md). - Trimmed the auto-generated 2025 entry block from this changelog.
2026-04-23 - Chat UX Commands and MOTD
Added
:last [N]— show last N messages retrieved directly from the log file (1–50, default 10), bypassing the 100-message in-memory ring buffer limit:search <keyword>— case-insensitive full-text search across the entire message history on disk; returns the most recent 15 matches:mute-joins— per-client toggle to silence join/leave system notifications; title bar shows[静音]when active- MOTD support — place
motd.txtin the state directory; users see it on connect and press any key to enter chat message_search()— new function inmessage.c/message.hfor log file keyword search with rolling result collection- Updated in-TUI help screens (English and Chinese) with new commands
2026-03-10 - SSH Runtime & Unix Interface Update
Fixed
- moved SSH handshake/auth/channel setup out of the main accept loop
- replaced synchronous room-wide fan-out with room update sequencing and per-client refresh
- switched idle session handling to
ssh_channel_poll_timeout()plus blocking reads so quiet sessions are not dropped incorrectly - made
-d/--state-dircreate the runtime state directory automatically
Added
- SSH exec commands:
help,health,users,stats --json,tail,post - PTY window-change handling for terminal resize
TNT_MAX_CONN_RATE_PER_IPfor per-IP connection-rate controltests/test_exec_mode.shtests/test_connection_limits.sh
Changed
TNT_MAX_CONN_PER_IPnow means concurrent sessions per IP- stress tests now disable rate-based blocking so they exercise concurrency instead of self-throttling
2026-01-22 - Security Audit Fixes
Comprehensive security hardening addressing 23 identified vulnerabilities across 6 categories.
Critical
- [AUTH] Add optional access token authentication (
TNT_ACCESS_TOKEN) - [AUTH] Implement IP-based rate limiting (10 conn/IP/60s, 5-min block after 5 auth failures)
- [AUTH] Add global connection limits (default: 64, configurable via
TNT_MAX_CONNECTIONS)
High Priority
- [BUFFER] Replace all
strcpy()withstrncpy()(3 locations) - [BUFFER] Add buffer overflow checking in
client_printf() - [BUFFER] Implement UTF-8 validation to prevent malformed input and overlong encodings
- [SSH] Upgrade RSA key from 2048 to 4096 bits
- [SSH] Fix key file permission race with atomic generation (umask + temp file + rename)
- [SSH] Add configurable bind address (
TNT_BIND_ADDR) and log level (TNT_SSH_LOG_LEVEL) - [CONCURRENCY] Fix
room_broadcast()reference counting race - [CONCURRENCY] Fix
tui_render_screen()message array TOCTOU via snapshot approach - [CONCURRENCY] Fix
handle_key()scroll position TOCTOU
Medium Priority
- [INPUT] Add username validation rejecting shell metacharacters and control chars
- [INPUT] Sanitize message content to prevent log injection attacks
- [INPUT] Enhance
message_load()with field length and timestamp validation - [RESOURCE] Convert message position array from fixed 1000 to dynamic allocation
- [RESOURCE] Enhance
setup_host_key()validation (size, permissions, auto-regeneration) - [RESOURCE] Improve thread cleanup with proper pthread_attr and error handling
New Environment Variables
TNT_ACCESS_TOKEN- Optional password for authentication (backward compatible)TNT_BIND_ADDR- Bind address (default: 0.0.0.0)TNT_SSH_LOG_LEVEL- SSH logging verbosity 0-4 (default: 1)TNT_RATE_LIMIT- Enable/disable rate limiting (default: 1)TNT_MAX_CONNECTIONS- Max concurrent connections (default: 64)TNT_MAX_CONN_PER_IP- Max connections per IP (default: 5)
Security Summary
| Category | Fixes | Impact |
|---|---|---|
| Buffer Security | 3 | Prevents overflows, malformed UTF-8 |
| SSH Hardening | 4 | Stronger crypto, no races |
| Input Validation | 3 | Prevents injection, log poisoning |
| Resource Management | 3 | Handles large logs, prevents DoS |
| Authentication | 3 | Optional protection, rate limiting |
| Concurrency Safety | 3 | Eliminates races, crashes |
| TOTAL | 19 | 23 vulnerabilities fixed |
All changes maintain backward compatibility. Server remains open by default.
2025-12-02 - Stability & Testing Update
Fixed
- Double colon bug in vim command mode (
:key consumed properly) - strtok data corruption in command output rendering
- Use-after-free race condition (added reference counting)
- SSH read blocking issues (added timeouts)
- PTY request infinite loop
- Message history memory waste (optimized loading)
Added
- Reference counting for thread-safe client cleanup
- SSH read timeout (30s) and error handling
- UTF-8 incomplete sequence detection
- AddressSanitizer build target (
make asan) - Basic functional tests (
test_basic.sh) - Stress testing script (
test_stress.sh) - Static analysis target (
make check) - Developer documentation (HACKING)
Changed
- Improved error handling throughout
- Better memory management in message loading