[Pkg-openldap-devel] Bug#823232: Bug#823232: libldap-2.4-2: Cannot connect to LDAP server with invalid (self-signed or non-standard CA signed) certificate

Ryan Tandy ryan at nardis.ca
Sat May 14 23:57:13 UTC 2016


Control: tag -1 confirmed upstream
Control: retitle -1 libldap-2.4-2: default TLS context setup ignores options set on connection

Hello,

Sorry for the delayed response.

On Mon, May 02, 2016 at 05:44:58PM +0300, Aki Tuomi wrote:
>Most simple usecase:
>1. Install slapd with non-default CA signed certificate
>2. Try connect with openldap -Z -H ldap://server ...
>
>Expected behaviour
>Invalid cert ignored, and TLS continues
>
>Actual behaviour
>Failure with non-descriptive error, debug shows
>ldap_start_tls: Connect error (-11)

This appears to work for me, tested as follows:

- in a clean jessie system, apt-get install ssl-cert slapd ldap-utils
- add the openldap user to the ssl-cert group
- configure slapd to use the snakeoil (self-signed) certs

$ LDAPTLS_REQCERT=allow ldapwhoami -ZZ -x
anonymous

Another option, which I personally would prefer, is to set the CA cert 
just for LDAP:

$ LDAPTLS_CACERT=/etc/ssl/certs/ssl-cert-snakeoil.pem ldapwhoami -ZZ -x
anonymous

>Workaround, of course, is to install the non-standard CA as trusted CA
>certificate. But the man page *does* say that it really should work.

Right, installing the non-standard CA system wide should not be 
necessary, for either of the options above.

>The same behaviour occurs with direct LDAP library usage with
>
>  int opt = LDAP_OPT_X_TLS_ALLOW;
>  ldap_set_option(conn->conn, LDAP_OPT_X_TLS, &opt);
>  ldap_set_option(conn->conn, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt);
>
>Again, this should allow non-trusted certificate on peer, which is appears
>not to do.

As a side note, the LDAP_OPT_X_TLS option is deprecated in favour of 
ldap_start_tls(3):

http://www.openldap.org/lists/openldap-software/200706/msg00159.html

The documentation apparently doesn't talk about this, but it looks like 
what happens is that you get a default TLS context, initialized using 
the global options, unless you specifically ask for a new one using 
LDAP_OPT_X_TLS_NEWCTX.

So this works:

	int require_cert = LDAP_OPT_X_TLS_ALLOW;
	rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &require_cert);
	assert(rc == LDAP_SUCCESS);

	int new_ctx = 0;
	rc = ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &new_ctx);
	assert (rc == LDAP_SUCCESS);

	rc = ldap_start_tls_s(ld, NULL, NULL);
	assert(rc == LDAP_SUCCESS);

and this works:

	int require_cert = LDAP_OPT_X_TLS_ALLOW;
	rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &require_cert);
	assert(rc == LDAP_SUCCESS);

	LDAP *ld;
	rc = ldap_initialize(&ld, "ldap://");
	assert(rc == LDAP_SUCCESS);

	rc = ldap_start_tls_s(ld, NULL, NULL);
	assert(rc == LDAP_SUCCESS);

but this doesn't work:

	int require_cert = LDAP_OPT_X_TLS_ALLOW;
	rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &require_cert);
	assert(rc == LDAP_SUCCESS);

	rc = ldap_start_tls_s(ld, NULL, NULL);
	assert(rc == LDAP_SUCCESS);

Other people have noticed this, too:

http://stackoverflow.com/a/27713355
http://www.openldap.org/its/?findid=7843

I'm guessing this is intended behaviour, and the documentation should be 
clarified. I'll follow up with upstream. Thanks for the report!



More information about the Pkg-openldap-devel mailing list