[PATCH 0/3] LDAP server-side STARTTLS support
Hi Michal, This series adds server-side STARTTLS support for the LDAP protocol handler (RFC 2830). Three patches are attached: 0001 — core feature (src/protocol.c only) 0002 — automated test plugin for make check 0003 — optional Docker-based live integration test [RFC] Background ---------- stunnel already supports LDAP STARTTLS on the client side (ldap_client_middle): it connects to an LDAP backend, sends a StartTLS ExtendedRequest, waits for the success response, and then performs the TLS handshake toward the backend. The server side was missing. Without it, stunnel could not act as a TLS termination proxy in front of a plain LDAP backend for clients that initiate connections using STARTTLS — a common deployment pattern where legacy LDAP clients that do not support LDAPS (TLS-on-connect) still expect to negotiate TLS via STARTTLS before sending credentials. Patch 1 — core feature ----------------------- Two new functions in src/protocol.c, mirroring the structure of the existing client-side implementation: ldap_server_init Sets connect_before_ssl=1 so stunnel establishes the TCP connection to the backend before starting the TLS handshake with the local client. ldap_server_middle Reads the incoming LDAPMessage from the client and validates it as a StartTLS ExtendedRequest (APPLICATION 23, OID 1.3.6.1.4.1.1466.20037). Extracts the messageID and sends back a well-formed StartTLS ExtendedResponse (APPLICATION 24, resultCode=success) with the matching messageID. stunnel then performs SSL_accept with the client. WinLDAP-style four-byte length encoding is handled, matching the existing client-side behaviour. Both functions are registered in the PROTOCOL dispatch table under the existing "ldap" name, so protocol = ldap now works for both client and server services. Patch 2 — automated tests -------------------------- p28_ldap_starttls.py adds two tests to make check: Test 281: the Python test harness performs the RFC 2830 StartTLS exchange directly against a stunnel server (protocol=ldap), then upgrades to TLS via asyncio's loop.start_tls(), exercising ldap_server_middle in isolation. Test 282: a full client→server proxy chain where both stunnel instances run with protocol=ldap, exercising ldap_client_middle and ldap_server_middle together end-to-end. Patch 3 — live integration test [RFC / optional] ------------------------------------------------- ldap_starttls_live_test.sh is a shell script that runs against a real OpenLDAP server (osixia/openldap) in Docker. It requires Docker, ldapsearch/ldapadd, and openssl, so it is not part of make check. I'm sending it as an optional follow-up in case it is useful for manual verification or as a starting point for a CI stage. Feel free to drop it if it does not fit the project's test infrastructure. License ------- I dedicate my contributions in this patch series to the public domain, in line with the contribution policy stated in CREDITS.md. Regards, Steffen Heil Geschäftsführer _______________________________________________________________________________ secforge GmbH Starterzentrum | Campus A1.1 | 66123 Saarbrücken | Deutschland Phone: +49 179 2339260 | +49 681 93355440 E-Mail: steffen.heil@secforge.de<mailto:steffen.heil@secforge.de> Web: https://www.secforge.de Registergericht: Amtsgerichts Saarbrücken | HRB 109882 Geschäftsführer: Steffen Heil, Dr. Mikhail Kovalev
Hi Michał, hi all, back in May I sent a small patch series adding server-side STARTTLS support for the LDAP protocol handler (RFC 2830) — see „[PATCH 0/3] LDAP server-side STARTTLS support“ from 13 May 2026 (quoted below). It was branched off 5.78. I saw that 5.79 and 5.80 have been released in the meantime. Since 5.80 was a security release addressing two CVEs, I completely understand that the focus was elsewhere — so no pressure at all. I just wanted to gently follow up: is LDAP server-side STARTTLS something you would consider for a future (normal-urgency) release? I'd just like to know whether it's worth pursuing. I do think it would be useful beyond our own setup: terminating STARTTLS in front of a plain LDAP backend is a fairly common deployment pattern. STARTTLS (RFC 2830) is the standards-track way to secure LDAP on the regular port — as opposed to LDAPS (TLS-on-connect on 636) — and since stunnel already implements the client side, this would round out its LDAP support. We have in fact already rebased the series onto 5.80 internally — I just didn't want to spam the list with an unsolicited resend unless there is interest. If the feature is of interest, I'd be glad to send the rebased version and do whatever else is needed to get it into a mergeable shape — adjusting the coding style to match the project's conventions, reworking or reducing the tests, resubmitting the series inline instead of as attachments, or adding documentation. Just let me know what you'd prefer. Of course, if it's not something you'd want upstream, that's absolutely fine too — I'd appreciate a quick note either way. Thank you very much for stunnel and for your work. Best regards, Steffen Heil ________________________________ ________________________________ From: Steffen Heil | secforge Sent: Wednesday, 13 May 2026 14:40:17 To: stunnel-users@lists.stunnel.org <stunnel-users@lists.stunnel.org> Cc: Michal.Trojnara@stunnel.org <Michal.Trojnara@stunnel.org> Subject: [PATCH 0/3] LDAP server-side STARTTLS support Hi Michal, This series adds server-side STARTTLS support for the LDAP protocol handler (RFC 2830). Three patches are attached: 0001 — core feature (src/protocol.c only) 0002 — automated test plugin for make check 0003 — optional Docker-based live integration test [RFC] Background ---------- stunnel already supports LDAP STARTTLS on the client side (ldap_client_middle): it connects to an LDAP backend, sends a StartTLS ExtendedRequest, waits for the success response, and then performs the TLS handshake toward the backend. The server side was missing. Without it, stunnel could not act as a TLS termination proxy in front of a plain LDAP backend for clients that initiate connections using STARTTLS — a common deployment pattern where legacy LDAP clients that do not support LDAPS (TLS-on-connect) still expect to negotiate TLS via STARTTLS before sending credentials. Patch 1 — core feature ----------------------- Two new functions in src/protocol.c, mirroring the structure of the existing client-side implementation: ldap_server_init Sets connect_before_ssl=1 so stunnel establishes the TCP connection to the backend before starting the TLS handshake with the local client. ldap_server_middle Reads the incoming LDAPMessage from the client and validates it as a StartTLS ExtendedRequest (APPLICATION 23, OID 1.3.6.1.4.1.1466.20037). Extracts the messageID and sends back a well-formed StartTLS ExtendedResponse (APPLICATION 24, resultCode=success) with the matching messageID. stunnel then performs SSL_accept with the client. WinLDAP-style four-byte length encoding is handled, matching the existing client-side behaviour. Both functions are registered in the PROTOCOL dispatch table under the existing "ldap" name, so protocol = ldap now works for both client and server services. Patch 2 — automated tests -------------------------- p28_ldap_starttls.py adds two tests to make check: Test 281: the Python test harness performs the RFC 2830 StartTLS exchange directly against a stunnel server (protocol=ldap), then upgrades to TLS via asyncio's loop.start_tls(), exercising ldap_server_middle in isolation. Test 282: a full client→server proxy chain where both stunnel instances run with protocol=ldap, exercising ldap_client_middle and ldap_server_middle together end-to-end. Patch 3 — live integration test [RFC / optional] ------------------------------------------------- ldap_starttls_live_test.sh is a shell script that runs against a real OpenLDAP server (osixia/openldap) in Docker. It requires Docker, ldapsearch/ldapadd, and openssl, so it is not part of make check. I'm sending it as an optional follow-up in case it is useful for manual verification or as a starting point for a CI stage. Feel free to drop it if it does not fit the project's test infrastructure. License ------- I dedicate my contributions in this patch series to the public domain, in line with the contribution policy stated in CREDITS.md. Regards, Steffen Heil Geschäftsführer _______________________________________________________________________________ secforge GmbH Starterzentrum | Campus A1.1 | 66123 Saarbrücken | Deutschland Phone: +49 179 2339260 | +49 681 93355440 E-Mail: steffen.heil@secforge.de<mailto:steffen.heil@secforge.de> Web: https://www.secforge.de Registergericht: Amtsgerichts Saarbrücken | HRB 109882 Geschäftsführer: Steffen Heil, Dr. Mikhail Kovalev
participants (1)
-
Steffen Heil | secforge