[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