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>
(cherry picked from commit ff17aee5d1)
This commit is contained in:
Werner Koch 2021-05-26 15:49:14 +02:00
parent eb3a629154
commit 52cf32ce2f
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 128 additions and 16 deletions

View File

@ -125,6 +125,7 @@ enum cmd_and_opt_values {
oHTTPProxy, oHTTPProxy,
oLDAPProxy, oLDAPProxy,
oOnlyLDAPProxy, oOnlyLDAPProxy,
oLDAPServer,
oLDAPFile, oLDAPFile,
oLDAPTimeout, oLDAPTimeout,
oLDAPAddServers, oLDAPAddServers,
@ -260,6 +261,8 @@ static gpgrt_opt_t opts[] = {
N_("|HOST|use HOST for LDAP queries")), N_("|HOST|use HOST for LDAP queries")),
ARGPARSE_s_n (oOnlyLDAPProxy, "only-ldap-proxy", ARGPARSE_s_n (oOnlyLDAPProxy, "only-ldap-proxy",
N_("do not use fallback hosts with --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", ARGPARSE_s_s (oLDAPFile, "ldapserverlist-file",
N_("|FILE|read LDAP server list from FILE")), N_("|FILE|read LDAP server list from FILE")),
ARGPARSE_s_n (oLDAPAddServers, "add-servers", ARGPARSE_s_n (oLDAPAddServers, "add-servers",
@ -378,6 +381,11 @@ static int network_activity_seen;
/* A list of filenames registered with --hkp-cacert. */ /* A list of filenames registered with --hkp-cacert. */
static strlist_t hkp_cacert_filenames; 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. */ /* The timer tick used for housekeeping stuff. The second constant is used when a shutdown is pending. */
#define TIMERTICK_INTERVAL (60) #define TIMERTICK_INTERVAL (60)
@ -671,6 +679,7 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
set_dns_timeout (0); set_dns_timeout (0);
opt.connect_timeout = 0; opt.connect_timeout = 0;
opt.connect_quick_timeout = 0; opt.connect_quick_timeout = 0;
ldapserver_list_needs_reset = 1;
return 1; return 1;
} }
@ -759,6 +768,30 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
case oStandardResolver: enable_standard_resolver (1); break; case oStandardResolver: enable_standard_resolver (1); break;
case oRecursiveResolver: enable_recursive_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: case oKeyServer:
if (*pargs->r.ret_str) if (*pargs->r.ret_str)
add_to_strlist (&opt.keyserver, pargs->r.ret_str); add_to_strlist (&opt.keyserver, pargs->r.ret_str);
@ -1133,9 +1166,11 @@ main (int argc, char **argv)
if (cmd != aGPGConfTest && cmd != aGPGConfList && cmd != aGPGConfVersions) if (cmd != aGPGConfTest && cmd != aGPGConfList && cmd != aGPGConfVersions)
set_tor_mode (); set_tor_mode ();
/* Get LDAP server list from file. */ /* Get LDAP server list from file unless --ldapserver has been used. */
#if USE_LDAP #if USE_LDAP
if (!ldapfile) if (opt.ldapservers)
;
else if (!ldapfile)
{ {
ldapfile = make_filename (gnupg_homedir (), ldapfile = make_filename (gnupg_homedir (),
"dirmngr_ldapservers.conf", "dirmngr_ldapservers.conf",

View File

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

View File

@ -1140,11 +1140,13 @@ task_check_wkd_support (ctrl_t ctrl, const char *domain)
static const char hlp_ldapserver[] = static const char hlp_ldapserver[] =
"LDAPSERVER <data>\n" "LDAPSERVER [--clear] <data>\n"
"\n" "\n"
"Add a new LDAP server to the list of configured LDAP servers.\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" "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 static gpg_error_t
cmd_ldapserver (assuan_context_t ctx, char *line) 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); ctrl_t ctrl = assuan_get_pointer (ctx);
ldap_server_t server; ldap_server_t server;
ldap_server_t *last_next_p; ldap_server_t *last_next_p;
int clear_flag;
clear_flag = has_option (line, "--clear");
line = skip_options (line);
while (spacep (line)) while (spacep (line))
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. */ /* Skip an "ldap:" prefix unless it is a valid ldap url. */
if (!strncmp (line, "ldap:", 5) && !(line[5] == '/' && line[6] == '/')) if (!strncmp (line, "ldap:", 5) && !(line[5] == '/' && line[6] == '/'))

View File

@ -14,7 +14,7 @@
@manpage dirmngr.8 @manpage dirmngr.8
@ifset manverb @ifset manverb
.B dirmngr .B dirmngr
\- CRL and OCSP daemon \- GnuPG's network access daemon
@end ifset @end ifset
@mansect synopsis @mansect synopsis
@ -424,10 +424,9 @@ configured LDAP server if the connection using the "proxy" failed.
@item --ldapserverlist-file @var{file} @item --ldapserverlist-file @var{file}
@opindex ldapserverlist-file @opindex ldapserverlist-file
Read a 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. This servers from this list are used after any servers set by a file instead of the default per-user ldap server list file. The default
client for its session. The default value for @var{file} is value for @var{file} is @file{dirmngr_ldapservers.conf}.
@file{dirmngr_ldapservers.conf}.
This server list file contains one LDAP server per line in the format This server list file contains one LDAP server per line in the format
@ -435,17 +434,45 @@ This server list file contains one LDAP server per line in the format
Lines starting with a @samp{#} are comments. Lines starting with a @samp{#} are comments.
The only defined flag is @code{ldaps} to specify that a TLS
connections shall be used. Flags are comma delimited; unknown flags
are ignored.
Note that as usual all strings entered are expected to be UTF-8 encoded. Note that as usual all strings entered are expected to be UTF-8 encoded.
Obviously this will lead to problems if the password has originally been Obviously this will lead to problems if the password has originally been
encoded as Latin-1. There is no other solution here than to put such a 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 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 won't show up readable).@footnote{The @command{gpgconf} tool might be
helpful for frontends as it enables editing this configuration file using 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} @item --ldaptimeout @var{secs}