• src/ssh/README.md deucessh.h ssh-internal.h ssh-trans.c ssh.c src/ssh/

    From Deuc¨@VERT to Git commit to main/sbbs/master on Sun May 3 19:11:38 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/57869c54b18727c02e23518a
    Modified Files:
    src/ssh/README.md deucessh.h ssh-internal.h ssh-trans.c ssh.c src/ssh/test/dssh_test_internal.h test_transport.c
    Log Message:
    DeuceSSH: per-session algorithm whitelist filters

    Add five setters that constrain a single session to a subset of
    the globally-registered algorithms, in caller-specified preference
    order, without disturbing the registry's "register once at startup"
    shape:

    dssh_session_set_kex_filter
    dssh_session_set_key_algo_filter
    dssh_session_set_enc_filter
    dssh_session_set_mac_filter
    dssh_session_set_comp_filter

    Motivating case: an app wants aes128-cbc available only on Mystic
    connections, not offered on every other SSH session it makes.
    Register both ciphers globally as before; on the Mystic session
    call dssh_session_set_enc_filter(sess, {"aes128-cbc"}, 1).

    Contract: NULL or count == 0 clears (= use everything registered,
    in registration order). Filter order becomes negotiation preference
    order. Names not registered are silently skipped. Names containing
    ',' return DSSH_ERROR_INVALID. Must be called before
    dssh_session_start(); returns DSSH_ERROR_TOOLATE afterwards.
    Caller-owned input; the library copies the strings.

    Internals: stored as a per-category CSV on the session.
    build_namelist gains a filter parameter Ä when non-NULL it walks
    the filter (in filter order) and emits each name that is actually
    registered, instead of walking the registry. negotiate_algo also
    gains a filter parameter for defense-in-depth so a malformed peer
    list cannot select a filtered name. The server-side host-key
    haskey loop applies the filter alongside its haskey() predicate.

    11 new tests in test_transport.c cover the helper, the build_namelist
    filter logic, the negotiate_algo gate, and every setter rejection
    path (comma, NULL element, empty string, NULL session, TOOLATE
    post-start, replace, clear). 19 existing call sites of build_namelist/negotiate_algo updated to pass NULL.

    OpenSSL: 3410/3410 tests pass. Botan: 3411/3411 tests pass.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net