mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
2b4cddf908
* 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
212 lines
5.3 KiB
C
212 lines
5.3 KiB
C
/* 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;
|
||
}
|