• src/sbbs3/websrvr.cpp

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Mon Feb 16 21:09:27 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/b210bfee35785deaeb57abdb
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    Add %p (server port) to custom log format supported directives

    <nelgin> DigitalMan would you mind implementing %p for server port please.
    The apache vhost combined logfile uses it.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Tue Feb 24 16:28:36 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/fd0b9d2bc21b13fa9840e190
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    Remove (long-deprecated) access.ars file support (use webctrl.ini instead)

    Fix issue #1083

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Sun Mar 8 05:28:49 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/0c0cb7c473285ab8c71f209a
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    Allocate extra byte for NUL-terminator in read_post_data()

    This looks like an off-by-one bug in this one call to realloc(), not adding one for the NUL terminator in this case.

    Potential cause of issue #1094

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deucе@VERT to Git commit to main/sbbs/master on Sun Mar 8 20:47:44 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/07ed41c51fd336b9d7c5d9b4
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    Add NUL to end of post data file

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wed May 6 19:41:53 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/3ad3f0282bcff37fa1926121
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: cast away two best-effort unchecked returns (CIDs 639932, 639941)

    CID 639932: remove(cleanup_file[i]) in close_request — best-effort
    cleanup of temporary request files; failure is benign.
    CID 639941: setsockopt(TCP_NODELAY) in http_session_thread — latency
    hint; failure is non-fatal. Also widen the bool nodelay to
    int so it has correct setsockopt() type.

    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wed May 6 19:41:53 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/62b41cd33f2fa4292d83710d
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: handle getuserdat failures in http_logon and check_ars (CIDs 516407, 516410, 639949)

    Both call sites set user.number then read the rest of the user record
    via getuserdat(). On read failure the user struct was left partially
    populated, then used for password comparison or downstream session
    state. Treat the failure as a system error: log it and either fall
    back to an unauthenticated session (http_logon) or reject the auth
    attempt (check_ars).

    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wed May 6 19:41:53 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/65d46495860f18fb2c9a5882
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: suppress send_error ORDER_REVERSAL false-positive (CID 631137)

    Coverity reports an ORDER_REVERSAL between link_list.mutex and
    jsrt_mutex when http_session_thread calls send_error() in the
    client-limit branches. The link_list helpers in this thread
    (loginAttempts, client_on, listCountMatches) acquire+release their
    list mutex internally — nothing holds a list mutex when send_error
    runs js_setup() which acquires jsrt_mutex. Annotate both 503/429
    send_error sites with a SUPPRESS plus rationale.

    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wed May 6 22:36:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/6ad832522da440e614b8fcdf
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: clamp tls_sent and explicit cast in sess_sendbuf return (CID 639935)

    The TLS path assigns 'result = tls_sent' where tls_sent is int and
    could theoretically be negative on cryptlib edge cases. Adding it
    to size_t 'sent' would underflow. Guard with 'if (result > 0)'.

    Also make the size_t-to-int returns explicit casts so Coverity sees
    the narrowing is intentional.

    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Wed May 6 22:51:40 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/c7df44f17c494f7277ac112e
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: skip getuserdat for anonymous sessions in http_logon

    Regression from 9e7649fe0: when http_logon is called with usr=NULL
    on an anonymous request (session->user.number == 0), getuserdat
    legitimately fails because user 0 doesn't exist, which now spams
    the log with '!ERROR reading user #0 data' on every anon hit.

    Only call getuserdat when there's an actual user number to read.

    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Wed May 6 23:04:20 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/c94f75aa58112c228a8cdce9
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: include protocol, IP, request, and ARS in no-auth log

    The "!No authentication information" debug log line now reports the
    protocol, client address, request line, and the ARS string that triggered
    the auth requirement, so it's actionable when WEB_OPT_DEBUG_RX is on.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Sat May 9 14:04:17 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/f7b10a614935817ba8965ec1
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: don't call destroy_session() with sentinel tls_sess value (-1)

    When TLS setup fails after add_private_key() returns an error, the code
    calls cryptDestroySession() directly and sets tls_sess = -1, then calls close_session_no_rb() which would pass -1 to destroy_session(), triggering
    a spurious "Destroying a session (-1) that's not in sess_list" error.

    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Thu Jun 4 09:44:21 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/50258e70bf63ba7a82af7515
    Modified Files:
    src/sbbs3/websrvr.cpp
    Log Message:
    websrvr: detect TLS client disconnect in session_check() (#1155)

    session_check()'s is_tls branch treated a readable socket as "connected"
    and latched session->tls_pending; once set, it returned "connected" on
    every later call without re-probing the socket. But a peer's TLS
    close_notify (and a FIN) arrive as readable bytes, so after an HTTPS
    client hung up, session_check() reported it connected forever. The
    JavaScript disconnect check in js_OperationCallback (ead5ccf16) relies on session_check(), so its abort never armed (offline_counter stayed 0): a badly-formed SSJS/XJS page that loops on mswait() without checking for disconnection (e.g. the webv4 user/system stats) ran forever, pinning its http_session thread, a MaxClients slot, and a CLOSE_WAIT socket -- a pile
    of zombie HTTPS clients in sbbsctrl/MQTT and eventual MaxClients
    exhaustion.

    Why this only bit Windows: socket_check() (xpdev) has two paths. On
    non-Windows builds it uses poll() (CFLAGS += -DPREFER_POLL, set only in build/Common.gmake, i.e. the GNU-make/Unix builds). poll() reports
    POLLHUP when the peer closes its end -- even while there is still buffered
    data to read -- and socket_check() returns false on POLLHUP before it
    ever runs the readable/MSG_PEEK logic. So on Unix the close was detected, session_check() returned false, and tls_pending never latched. Windows (MSBuild) does not define PREFER_POLL and uses select(), which has no
    POLLHUP equivalent: a closing TLS socket simply looks "readable"
    (MSG_PEEK returns the encrypted close_notify bytes), so the latch was set
    and the disconnect masked. The session_check() bug is platform-
    independent; poll()/POLLHUP merely hid it everywhere except Windows.

    Fix: drop the tls_pending liveness latch. Use peeked_valid (a decrypted
    byte already buffered) as the readable fast-path, and when the raw socket
    is readable, probe via cryptPopData(1 byte) -- which a raw MSG_PEEK
    cannot do -- to tell apart application data (connected; the byte is
    cached in session->peeked so the next sess_recv() returns it), CRYPT_ERROR_TIMEOUT (connected, no app data yet) and CRYPT_ERROR_COMPLETE
    (peer closed -> disconnected). The probe is non-blocking (CRYPT_OPTION_NET_READTIMEOUT == 0, set at session setup) and runs in the session's own thread, so there is no concurrent reader. Also close the
    socket in place in recvbufsocket() when session_check() reports a
    disconnect (it previously relied on the latch returning true and the
    following sess_recv() failing).

    Latch introduced in d93478b918 (famous-15-sons); the readable-as-
    connected + tls_pending set predates it (dbbfabf1b1, funky-27-foam).

    Validated on a production Windows server: CLOSE_WAIT count ~22 -> 0,
    sbbsctrl thread count 221 -> 25, and ran overnight with no zombie HTTPS clients.

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

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