1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00
gnupg/dirmngr/ldapserver.c
Werner Koch 2b4cddf908
dirmngr: Allow for non-URL specified ldap keyservers.
* dirmngr/server.c (cmd_ldapserver): Strip an optional prefix.
(make_keyserver_item): Handle non-URL ldap specs.
* dirmngr/dirmngr.h (struct ldap_server_s): Add fields starttls,
ldap_over_tls, and ntds.

* dirmngr/ldapserver.c (ldapserver_parse_one): Add for an empty host
string.  Improve error messages for the non-file case.  Support flags.
* dirmngr/ks-action.c (ks_action_help): Handle non-URL ldap specs.
(ks_action_search, ks_action_get, ks_action_put): Ditto.
* dirmngr/ks-engine-ldap.c: Include ldapserver.h.
(ks_ldap_help): Handle non-URL ldap specs.
(my_ldap_connect): Add args r_host and r_use_tls.  Rewrite to support
URLs and non-URL specified keyservers.
(ks_ldap_get): Adjust for changes in my_ldap_connect.
(ks_ldap_search): Ditto.
(ks_ldap_put): Ditto.
--

The idea here is to unify our use of URLS or colon delimited ldap
keyserver specification.  The requirement for percent escaping, for
example the bindname in an URLs, is cumbersome and prone to errors.
This we allow our classic colon delimited format as an alternative.
That format makes it also easy to specify flags to tell dirmngr
whether to use starttls or ldap-over-tls.  The code is nearly 100%
compatible to existing specification.  There is one ambiguity if the
hostname for CRL/X509 searches is just "ldap"; this can be solved by
prefixing it with "ldap:" (already implemented in gpgsm).

GnuPG-bug-id: 5405, 5452
2021-05-26 14:48:27 +02:00

212 lines
5.3 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* dirmngr.c - LDAP access
Copyright (C) 2008 g10 Code GmbH
This file is part of DirMngr.
DirMngr is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DirMngr is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "dirmngr.h"
#include "ldapserver.h"
/* Release the list of SERVERS. As usual it is okay to call this
function with SERVERS passed as NULL. */
void
ldapserver_list_free (ldap_server_t servers)
{
while (servers)
{
ldap_server_t tmp = servers->next;
xfree (servers->host);
xfree (servers->user);
if (servers->pass)
memset (servers->pass, 0, strlen (servers->pass));
xfree (servers->pass);
xfree (servers->base);
xfree (servers);
servers = tmp;
}
}
/* Parse a single LDAP server configuration line. Returns the server
or NULL in case of errors. The configuration line is assumed to be
colon seprated with these fields:
1. field: Hostname
2. field: Portnumber
3. field: Username
4. field: Password
5. field: Base DN
6. field: Flags
Flags are:
starttls := Use STARTTLS with a default port of 389
ldaptls := Tunnel LDAP trough a TLS tunnel with default port 636
plain := Switch to plain unsecured LDAP.
(The last of these 3 flags is the effective one)
ntds := Use Active Directory authentication
FILENAME and LINENO are used for diagnostic purposes only.
*/
ldap_server_t
ldapserver_parse_one (char *line,
const char *filename, unsigned int lineno)
{
char *p;
char *endp;
ldap_server_t server;
int fieldno;
int fail = 0;
/* Parse the colon separated fields. */
server = xtrycalloc (1, sizeof *server);
if (!server)
{
fail = 1;
goto leave;
}
for (fieldno = 1, p = line; p; p = endp, fieldno++ )
{
endp = strchr (p, ':');
if (endp)
*endp++ = '\0';
trim_spaces (p);
switch (fieldno)
{
case 1:
server->host = xtrystrdup (p);
if (!server->host)
fail = 1;
break;
case 2:
if (*p)
server->port = atoi (p);
break;
case 3:
server->user = xtrystrdup (p);
if (!server->user)
fail = 1;
break;
case 4:
if (*p && !server->user)
{
if (filename)
log_error (_("%s:%u: password given without user\n"),
filename, lineno);
else
log_error ("ldap: password given without user ('%s')\n", line);
fail = 1;
}
else if (*p)
{
server->pass = xtrystrdup (p);
if (!server->pass)
fail = 1;
}
break;
case 5:
if (*p)
{
server->base = xtrystrdup (p);
if (!server->base)
fail = 1;;
}
break;
case 6:
{
char **flags = NULL;
int i;
const char *s;
flags = strtokenize (p, ",");
if (!flags)
{
log_error ("strtokenize failed: %s\n",
gpg_strerror (gpg_error_from_syserror ()));
fail = 1;
break;
}
for (i=0; (s = flags[i]); i++)
{
if (!*s)
;
else if (!ascii_strcasecmp (s, "starttls"))
{
server->starttls = 1;
server->ldap_over_tls = 0;
}
else if (!ascii_strcasecmp (s, "ldaptls"))
{
server->starttls = 0;
server->ldap_over_tls = 1;
}
else if (!ascii_strcasecmp (s, "plain"))
{
server->starttls = 0;
server->ldap_over_tls = 0;
}
else if (!ascii_strcasecmp (s, "ntds"))
{
server->ntds = 1;
}
else
{
if (filename)
log_info (_("%s:%u: ignoring unknown flag '%s'\n"),
filename, lineno, s);
else
log_info ("ldap: unknown flag '%s' ignored in (%s)\n",
s, line);
}
}
xfree (flags);
}
break;
default:
/* (We silently ignore extra fields.) */
break;
}
}
leave:
if (fail)
{
if (filename)
log_info (_("%s:%u: skipping this line\n"), filename, lineno);
else
log_info ("ldap: error in server spec ('%s')\n", line);
ldapserver_list_free (server);
server = NULL;
}
return server;
}