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

Web: https://www.secforge.de

Registergericht:  Amtsgerichts Saarbrücken | HRB 109882 

Geschäftsführer: Steffen Heil, Dr. Mikhail Kovalev