[PATCH] dirmngr_ldap: support ldap secure connection(ldaps)

Neal H. Walfield neal at walfield.org
Sat Jun 6 03:02:41 CEST 2015


Hi,

I'm having trouble applying this patch.  It looks like the whitespace
got mangled in transit.  Can you please resend the patch or provide a
tree that I can pull from?

Thanks,

Neal

At Wed, 20 May 2015 16:27:11 +0300,
Dmitry Falko wrote:
> 
> Hello! 
> 
> I encountered a problem connecting to the LDAP server via TLS and
> wrote a small patch, send it as is. 
> 
> * dirmngr.h (ldap_server_s): add schema field 
> * dirmngr_ldap.c (fetch_ldap): ldaps support 
> * ldap.c (make_url, start_cert_fetch_ldap): add schema 
> * ldapserver.c (ldapserver_parse_one): parse schema 
> * server.c (lookup_cert_by_pattern): additional log info 
> 
> dirmngr_ldap can retrieve certificates from LDAP server 
> by TLS(using ldaps protocol). Protocol can be set in 
> dirmngr_ldapserver.conf: 
> hostname:port:username:password:base_dn:schema 
> If not set use ldap.By default dirmngr_ldap use 
> /etc/ssl/CA(dirmngr_ldap.c CA_CERT_DEFAULT) CA certificate, 
> user can set DIRMNGR_LDAP_CACERT env variable to 
> override this value. 
> --- 
> dirmngr/dirmngr.h | 1 + 
> dirmngr/dirmngr_ldap.c | 61
> +++++++++++++++++++++++++++++++++++++++++++++----- 
> dirmngr/ldap.c | 24 +++++++++++++++----- 
> dirmngr/ldapserver.c | 5 +++++ 
> dirmngr/server.c | 3 ++- 
> 5 files changed, 81 insertions(+), 13 deletions(-) 
> 
> diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h 
> index 4f037e7..3406494 100644 
> --- a/dirmngr/dirmngr.h 
> +++ b/dirmngr/dirmngr.h 
> @@ -46,6 +46,7 @@ struct ldap_server_s 
> char *user; 
> char *pass; 
> char *base; 
> + char *schema; 
> }; 
> typedef struct ldap_server_s *ldap_server_t; 
> 
> diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c 
> index 61a7e39..8bb739c 100644 
> --- a/dirmngr/dirmngr_ldap.c 
> +++ b/dirmngr/dirmngr_ldap.c 
> @@ -46,6 +46,8 @@ 
> /* For OpenLDAP, to enable the API that we're using. */ 
> # define LDAP_DEPRECATED 1 
> # include <ldap.h> 
> + /* FIXME: use configure script to set this define */ 
> +# define CA_CERT_DEFAULT ("/etc/ssl/CA") 
> #endif 
> 
> @@ -571,9 +573,10 @@ fetch_ldap (my_opt_t myopt, const char *url,
> const LDAPURLDesc *ludp) 
> LDAP *ld; 
> LDAPMessage *msg; 
> int rc = 0; 
> - char *host, *dn, *filter, *attrs[2], *attr; 
> + char *host, *dn, *filter, *attrs[2], *attr, *ca_cert, *ldap_url; 
> int port; 
> int ret; 
> + int err; 
> 
> host = myopt->host? myopt->host : ludp->lud_host; 
> port = myopt->port? myopt->port : ludp->lud_port; 
> @@ -583,6 +586,17 @@ fetch_ldap (my_opt_t myopt, const char *url,
> const LDAPURLDesc *ludp) 
> attrs[1] = NULL; 
> attr = attrs[0]; 
> 
> + ca_cert = getenv("DIRMNGR_LDAP_CACERT"); 
> + if(!ca_cert) 
> + { 
> + if (myopt->verbose) 
> + { 
> + log_info("Using default CA certificate"); 
> + } 
> + 
> + ca_cert = CA_CERT_DEFAULT; 
> + } 
> + 
> if (!port) 
> port = (ludp->lud_scheme && !strcmp (ludp->lud_scheme, "ldaps"))?
> 636:389; 
> 
> @@ -628,23 +642,58 @@ fetch_ldap (my_opt_t myopt, const char *url,
> const LDAPURLDesc *ludp) 
> 
> set_timeout (myopt); 
> + 
> + ldap_url = alloca(4 + strlen(ludp->lud_scheme) 
> + + strlen(host) 
> + + 5); /* for port */ 
> + sprintf(ldap_url, "%s://%s:%d", ludp->lud_scheme, host, port); 
> + 
> npth_unprotect (); 
> - ld = my_ldap_init (host, port); 
> + err = ldap_initialize(&ld, ldap_url) ; 
> npth_protect (); 
> - if (!ld) 
> + if (err != LDAP_SUCCESS) 
> { 
> - log_error (_("LDAP init to '%s:%d' failed: %s\n"), 
> - host, port, strerror (errno)); 
> + log_error (_("LDAP init to '%s' failed: %s\n"), 
> + ldap_url, ldap_err2string (errno)); 
> return -1; 
> } 
> npth_unprotect (); 
> + 
> + if(!strcmp (ludp->lud_scheme, "ldaps")) 
> + { 
> + /* Additional options for tls connection */ 
> + /*FIXME: LDAP_OPT_X_TLS_NEVER or LDAP_OPT_X_TLS_HARD, add option*/ 
> + int req_cert = LDAP_OPT_X_TLS_NEVER; 
> + 
> + err = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, 
> + ca_cert); 
> + npth_protect (); 
> + if(err != LDAP_SUCCESS) 
> + { 
> + log_error (_("setting ca-certificate failed: %s\n"), 
> + ldap_err2string (err)); 
> + return -1; 
> + } 
> + npth_unprotect (); 
> + err=ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, 
> + &req_cert); 
> + npth_protect (); 
> + if(err != LDAP_SUCCESS) 
> + { 
> + log_error (_("setting require certificate failed: %s\n"), 
> + ldap_err2string (err)); 
> + return -1; 
> + } 
> + npth_unprotect (); 
> + } 
> + 
> /* Fixme: Can we use MYOPT->user or is it shared with other theeads?.
> */ 
> ret = my_ldap_simple_bind_s (ld, myopt->user, myopt->pass); 
> npth_protect (); 
> if (ret) 
> { 
> log_error (_("binding to '%s:%d' failed: %s\n"), 
> - host, port, strerror (errno)); 
> + host, port, ldap_err2string (errno)); 
> ldap_unbind (ld); 
> return -1; 
> } 
> diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c 
> index e4c6aa2..d4e0730 100644 
> --- a/dirmngr/ldap.c 
> +++ b/dirmngr/ldap.c 
> @@ -423,10 +423,10 @@ escape4url (const char *string) 
> need the host and port because this will be specified using the 
> override options. */ 
> static gpg_error_t 
> -make_url (char **url, const char *dn, const char *filter) 
> +make_url (char **url, const char *dn, const char *filter, const char
> *schema) 
> { 
> gpg_error_t err; 
> - char *u_dn, *u_filter; 
> + char *u_dn, *u_filter, *u_schema; 
> char const attrs[] = (USERCERTIFICATE "," 
> /* USERSMIMECERTIFICATE "," */ 
> CACERTIFICATE "," 
> @@ -434,6 +434,10 @@ make_url (char **url, const char *dn, const char
> *filter) 
> 
> *url = NULL; 
> 
> + u_schema = escape4url (schema); 
> + if(!u_schema) 
> + return gpg_error_from_errno (errno); 
> + 
> u_dn = escape4url (dn); 
> if (!u_dn) 
> return gpg_error_from_errno (errno); 
> @@ -445,7 +449,8 @@ make_url (char **url, const char *dn, const char
> *filter) 
> xfree (u_dn); 
> return err; 
> } 
> - *url = malloc ( 8 + strlen (u_dn) 
> + *url = malloc ( 4 + strlen (schema) 
> + + strlen (u_dn) 
> + 1 + strlen (attrs) 
> + 5 + strlen (u_filter) + 1 ); 
> if (!*url) 
> @@ -456,12 +461,14 @@ make_url (char **url, const char *dn, const char
> *filter) 
> return err; 
> } 
> 
> - stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (*url, "ldap:///"), 
> + stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (stpcpy(*url,
> u_schema), 
> + ":///"), 
> u_dn), 
> "?"), 
> attrs), 
> "?sub?"), 
> u_filter); 
> + xfree (u_schema); 
> xfree (u_dn); 
> xfree (u_filter); 
> return 0; 
> @@ -525,6 +532,7 @@ start_cert_fetch_ldap (ctrl_t ctrl,
> cert_fetch_context_t *context, 
> const char *user; 
> const char *pass; 
> const char *base; 
> + const char *schema; 
> const char *argv[50]; 
> int argc; 
> char portbuf[30], timeoutbuf[30]; 
> @@ -538,6 +546,7 @@ start_cert_fetch_ldap (ctrl_t ctrl,
> cert_fetch_context_t *context, 
> user = server->user; 
> pass = server->pass; 
> base = server->base; 
> + schema = server->schema; 
> } 
> else /* Use a default server. */ 
> return gpg_error (GPG_ERR_NOT_IMPLEMENTED); 
> @@ -545,6 +554,9 @@ start_cert_fetch_ldap (ctrl_t ctrl,
> cert_fetch_context_t *context, 
> if (!base) 
> base = ""; 
> 
> + if(!schema) 
> + schema = "ldap"; 
> + 
> argc = 0; 
> if (pass) /* Note: Must be the first item. */ 
> { 
> @@ -606,9 +618,9 @@ start_cert_fetch_ldap (ctrl_t ctrl,
> cert_fetch_context_t *context, 
> return gpg_error (GPG_ERR_INV_USER_ID); 
> } 
> if ((sl->flags & 1)) 
> - err = make_url (&url, sl->d, "objectClass=*"); 
> + err = make_url (&url, sl->d, "objectClass=*", schema); 
> else 
> - err = make_url (&url, base, sl->d); 
> + err = make_url (&url, base, sl->d, schema); 
> free_strlist (sl); 
> if (err) 
> { 
> diff --git a/dirmngr/ldapserver.c b/dirmngr/ldapserver.c 
> index 16e13e2..87c8b47 100644 
> --- a/dirmngr/ldapserver.c 
> +++ b/dirmngr/ldapserver.c 
> @@ -115,6 +115,11 @@ ldapserver_parse_one (char *line, 
> server->base = xstrdup (p); 
> break; 
> 
> + case 6: 
> + if (*p) 
> + server->schema = xstrdup (p); 
> + break; 
> + 
> default: 
> /* (We silently ignore extra fields.) */ 
> break; 
> diff --git a/dirmngr/server.c b/dirmngr/server.c 
> index 1b7e9e9..bcf83f9 100644 
> --- a/dirmngr/server.c 
> +++ b/dirmngr/server.c 
> @@ -1259,7 +1259,8 @@ lookup_cert_by_pattern (assuan_context_t ctx,
> char *line, 
> ldap_server_t ldapserver = ldapserver_iter.server; 
> 
> if (DBG_LOOKUP) 
> - log_debug ("cmd_lookup: trying %s:%d base=%s\n", 
> + log_debug ("cmd_lookup: trying %s://%s:%d base=%s\n", 
> + ldapserver->schema ? ldapserver->schema: "ldap", 
> ldapserver->host, ldapserver->port, 
> ldapserver->base?ldapserver->base : "[default]"); 
> 
> -- 
> 1.9.1 
> 
> -- 
> Best Regards! 
> 



More information about the Gnupg-devel mailing list