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
Registergericht: Amtsgerichts Saarbrücken |
HRB 109882
Geschäftsführer: Steffen Heil, Dr. Mikhail Kovalev