Hello list.
I'm trying to extend nagios check_ldap plugin to also check LDAP certificate expiration. Equivalent code in check_http work directly at socket level, and is not directly transposable, as check_ldap works at higher level, relying on openldap libraries to manage its connection.
The code manipulates an opaque LDAP *ld connection handle. I had a quick look at openldap code, in libraries/libldap/tls.c, to see how this handle could be used to access the x509 certificate:
LDAPConn *conn = NULL; Sockbuf *sb = NULL; SSL *ssl = NULL; X509 *certificate = NULL;
conn = ld->ld_defconn; sb = conn->lconn_sb; ssl = ldap_pvt_tls_sb_ctx(sb); certificate = tls_get_cert(ssl);
However, all those types are defined in libraries/libldap/ldap-int.h header, meaning those are for internal use only. I had a quick look at IETF LDAP C draft found in openldap sources, but I couldn't find anything related to the topic. So, what's the proper way for doing this ?
On Tue, 2 Dec 2008, Guillaume Rousse wrote:
The code manipulates an opaque LDAP *ld connection handle. I had a quick look at openldap code, in libraries/libldap/tls.c, to see how this handle could be used to access the x509 certificate:
LDAPConn *conn = NULL; Sockbuf *sb = NULL; SSL *ssl = NULL; X509 *certificate = NULL;
conn = ld->ld_defconn; sb = conn->lconn_sb; ssl = ldap_pvt_tls_sb_ctx(sb); certificate = tls_get_cert(ssl);
However, all those types are defined in libraries/libldap/ldap-int.h header, meaning those are for internal use only. I had a quick look at IETF LDAP C draft found in openldap sources, but I couldn't find anything related to the topic. So, what's the proper way for doing this ?
ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl);
Philip Guenther
Philip Guenther a écrit :
On Tue, 2 Dec 2008, Guillaume Rousse wrote:
The code manipulates an opaque LDAP *ld connection handle. I had a quick look at openldap code, in libraries/libldap/tls.c, to see how this handle could be used to access the x509 certificate:
LDAPConn *conn = NULL; Sockbuf *sb = NULL; SSL *ssl = NULL; X509 *certificate = NULL;
conn = ld->ld_defconn; sb = conn->lconn_sb; ssl = ldap_pvt_tls_sb_ctx(sb); certificate = tls_get_cert(ssl);
However, all those types are defined in libraries/libldap/ldap-int.h header, meaning those are for internal use only. I had a quick look at IETF LDAP C draft found in openldap sources, but I couldn't find anything related to the topic. So, what's the proper way for doing this ?
ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl);
Excellent, thanks.
However, I just found out it only work if secure connection was made through ldap_start_tls_s(ld, NULL, NULL) call, and not through ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) earlier in the plugin code. Is this expected behaviour (I have to confess I'm not really aware of the difference between those methods) ?
Here is my own code:
int ldap_check_cert (LDAP *ld) { SSL *ssl; int rc;
rc = ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl); if (rc == LDAP_OPT_ERROR || ssl == null) { printf ("%s\n",_("CRITICAL - Cannot retrieve ssl session from connection.")); return STATE_CRITICAL; } return np_net_ssl_check_cert_real(ssl, days_till_exp); }
And here are the two different ways to initialise a secure connection:
if (ld_port == LDAPS_PORT || ssl_on_connect) { asprintf (&SERVICE, "LDAPS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) /* ldaps: set option tls */ tls = LDAP_OPT_X_TLS_HARD; if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldaps_option"); printf (_("Could not init TLS at port %i!\n"), ld_port); return STATE_CRITICAL; }
if (check_cert == TRUE) return ldap_check_cert(ld); } else if (starttls) { asprintf (&SERVICE, "LDAP-TLS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) /* ldap with startTLS: set option version */ if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS ) { if (version < LDAP_VERSION3) { version = LDAP_VERSION3; ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); } } /* call start_tls */ if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_start_tls"); printf (_("Could not init startTLS at port %i!\n"), ld_port); return STATE_CRITICAL; }
if (check_cert == TRUE) return ldap_check_cert(ld); }
openldap-software@openldap.org