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

Dmitry Falko dfalko at digiflak.com
Fri May 22 10:26:14 CEST 2015


Hello!

Why my patch ignored? It's bad, or useless?

20.05.2015 16:27, 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!
>
>
>
> _______________________________________________
> Gnupg-devel mailing list
> Gnupg-devel at gnupg.org
> http://lists.gnupg.org/mailman/listinfo/gnupg-devel

-- 
C Уважением, Дмитрий!

-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/attachments/20150522/485b4082/attachment.html>


More information about the Gnupg-devel mailing list