dirmngr: New option --ldapserver

* dirmngr/dirmngr.c (opts): Add option --ldapserver.
(ldapserver_list_needs_reset): New var.
(parse_rereadable_options): Implement option.
(main): Ignore dirmngr_ldapservers.conf if no --ldapserver is used.

* dirmngr/server.c (cmd_ldapserver): Add option --clear and list
configured servers if none are given.
--

This option allows to specify LDAP keyserver in dirmngr instead of
using gpgsm.conf.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-05-26 15:49:14 +02:00
parent 2b4cddf908
commit ff17aee5d1
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 127 additions and 10 deletions

View File

@ -124,6 +124,7 @@ enum cmd_and_opt_values {
oHTTPProxy,
oLDAPProxy,
oOnlyLDAPProxy,
oLDAPServer,
oLDAPFile,
oLDAPTimeout,
oLDAPAddServers,
@ -209,6 +210,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_n (oOnlyLDAPProxy, "only-ldap-proxy",
N_("do not use fallback hosts with --ldap-proxy")),
ARGPARSE_s_s (oLDAPServer, "ldapserver",
N_("|SPEC|use this keyserver to lookup keys")),
ARGPARSE_s_s (oLDAPFile, "ldapserverlist-file",
N_("|FILE|read LDAP server list from FILE")),
ARGPARSE_s_n (oLDAPAddServers, "add-servers",
@ -344,6 +347,11 @@ static int network_activity_seen;
/* A list of filenames registred with --hkp-cacert. */
static strlist_t hkp_cacert_filenames;
/* A flag used to clear the list of ldapservers iff --ldapserver is
* given on the command line or one of the conf files. In this case we
* want to clear all old specifications through the legacy
* dirmngr_ldapservers.conf. */
static int ldapserver_list_needs_reset;
/* The timer tick used for housekeeping stuff. The second constant is used when a shutdown is pending. */
#define TIMERTICK_INTERVAL (60)
@ -637,6 +645,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
set_dns_timeout (0);
opt.connect_timeout = 0;
opt.connect_quick_timeout = 0;
ldapserver_list_needs_reset = 1;
return 1;
}
@ -725,6 +734,30 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
case oStandardResolver: enable_standard_resolver (1); break;
case oRecursiveResolver: enable_recursive_resolver (1); break;
case oLDAPServer:
{
ldap_server_t server;
char *p;
p = pargs->r.ret_str;
if (!strncmp (p, "ldap:", 5) && !(p[5] == '/' && p[6] == '/'))
p += 5;
server = ldapserver_parse_one (p, NULL, 0);
if (server)
{
if (ldapserver_list_needs_reset)
{
ldapserver_list_needs_reset = 0;
ldapserver_list_free (opt.ldapservers);
opt.ldapservers = NULL;
}
server->next = opt.ldapservers;
opt.ldapservers = server;
}
}
break;
case oKeyServer:
if (*pargs->r.ret_str)
add_to_strlist (&opt.keyserver, pargs->r.ret_str);
@ -1087,9 +1120,11 @@ main (int argc, char **argv)
post_option_parsing ();
/* Get LDAP server list from file. */
/* Get LDAP server list from file unless --ldapserver has been used. */
#if USE_LDAP
if (!ldapfile)
if (opt.ldapservers)
;
else if (!ldapfile)
{
ldapfile = make_filename (gnupg_homedir (),
"dirmngr_ldapservers.conf",

View File

@ -519,7 +519,9 @@ my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
const char *bindname;
const char *password;
const char *basedn_arg;
#ifndef HAVE_W32_SYSTEM
char *tmpstr;
#endif
if (r_basedn)
*r_basedn = NULL;

View File

@ -1140,11 +1140,13 @@ task_check_wkd_support (ctrl_t ctrl, const char *domain)
static const char hlp_ldapserver[] =
"LDAPSERVER <data>\n"
"LDAPSERVER [--clear] <data>\n"
"\n"
"Add a new LDAP server to the list of configured LDAP servers.\n"
"DATA is in the same format as expected in the configure file.\n"
"An optional prefix \"ldap:\" is allowed.";
"An optional prefix \"ldap:\" is allowed. With no args all\n"
"configured ldapservers are listed. Option --clear removes all\n"
"servers configured in this session.";
static gpg_error_t
cmd_ldapserver (assuan_context_t ctx, char *line)
{
@ -1152,11 +1154,57 @@ cmd_ldapserver (assuan_context_t ctx, char *line)
ctrl_t ctrl = assuan_get_pointer (ctx);
ldap_server_t server;
ldap_server_t *last_next_p;
int clear_flag;
clear_flag = has_option (line, "--clear");
line = skip_options (line);
while (spacep (line))
line++;
if (*line == '\0')
return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
if (clear_flag)
{
#if USE_LDAP
ldapserver_list_free (ctrl->server_local->ldapservers);
#endif /*USE_LDAP*/
ctrl->server_local->ldapservers = NULL;
}
if (!*line && clear_flag)
return leave_cmd (ctx, 0);
if (!*line)
{
/* List all ldapservers. */
struct ldapserver_iter ldapserver_iter;
char *tmpstr;
char portstr[20];
for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
!ldapserver_iter_end_p (&ldapserver_iter);
ldapserver_iter_next (&ldapserver_iter))
{
server = ldapserver_iter.server;
if (server->port)
snprintf (portstr, sizeof portstr, "%d", server->port);
else
*portstr = 0;
tmpstr = xtryasprintf ("ldap:%s:%s:%s:%s:%s:%s%s:",
server->host? server->host : "",
portstr,
server->user? server->user : "",
server->pass? "[not_shown]": "",
server->base? server->base : "",
server->starttls ? "starttls" :
server->ldap_over_tls ? "ldaptls" : "none",
server->ntds ? ",ntds" : "");
if (!tmpstr)
return leave_cmd (ctx, gpg_error_from_syserror ());
dirmngr_status (ctrl, "LDAPSERVER", tmpstr, NULL);
xfree (tmpstr);
}
return leave_cmd (ctx, 0);
}
/* Skip an "ldap:" prefix unless it is a valid ldap url. */
if (!strncmp (line, "ldap:", 5) && !(line[5] == '/' && line[6] == '/'))

View File

@ -14,7 +14,7 @@
@manpage dirmngr.8
@ifset manverb
.B dirmngr
\- CRL and OCSP daemon
\- GnuPG's network access daemon
@end ifset
@mansect synopsis
@ -424,13 +424,13 @@ configured LDAP server if the connection using the "proxy" failed.
@item --ldapserverlist-file @var{file}
@opindex ldapserverlist-file
Read the list of LDAP servers to consult for CRLs and certificates from
Read the list of LDAP servers to consult for CRLs and X.509 certificates from
file instead of the default per-user ldap server list file. The default
value for @var{file} is @file{dirmngr_ldapservers.conf}.
This server list file contains one LDAP server per line in the format
@sc{hostname:port:username:password:base_dn}
@sc{hostname:port:username:password:base_dn:flags}
Lines starting with a @samp{#} are comments.
@ -440,7 +440,39 @@ encoded as Latin-1. There is no other solution here than to put such a
password in the binary encoding into the file (i.e. non-ascii characters
won't show up readable).@footnote{The @command{gpgconf} tool might be
helpful for frontends as it enables editing this configuration file using
percent-escaped strings.}
percent-escaped strings.}jj
@item --ldapserver @var{spec}
@opindex ldapserver
This is an alternative way to specify LDAP servers for CRL and X.509
certificate retrieval. If this option is used the servers configured
in @file{dirmngr_ldapservers.conf} (or the file given by
@option{--ldapserverlist-file}) are cleared. Reloading dirmngr will
consider these again will in no case use those from
@file{dirmngr_ldapservers.conf} again. The @var{spec} is either a
proper LDAP URL or a colon delimited list of the form
@sc{hostname:port:username:password:base_dn:flags:}
with an optional prefix of @code{ldap:} (but without the two slashes
which would turn this into a proper LDAP URL). @sc{flags} is a list
of one or more comma delimited keywords:
@table @code
@item plain
The default: Do not use a TLS secured connection at all; the default
port is 389.
@item starttls
Use STARTTLS to secure the connection; the default port is 389.
@item ldaptls
Tunnel LDAP through a TLS connection; the default port is 636.
@item ntds
On Windows authenticate the LDAP connection using the Active Directory
with the current user.
@end table
Note that in an URL style specification the scheme @code{ldaps://}
refers to STARTTLS and _not_ to LDAP-over-TLS.
@item --ldaptimeout @var{secs}