mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpgsm: Allow sepcification of ldaps servers.
* sm/gpgsm.h (struct keyserver_spec): Add field use_ldaps. * sm/gpgsm.c (parse_keyserver_line): Parse flags. * sm/call-dirmngr.c (prepare_dirmngr): Send ldaps flag to the dirmngr. * dirmngr/dirmngr.h (struct ldap_server_s): Add field use_ldaps. * dirmngr/ldapserver.c (ldapserver_parse_one): Parse flags. * dirmngr/ldap.c (start_cert_fetch_ldap): Call wrapper with --tls. * dirmngr/dirmngr_ldap.c: New option --tls. (fetch_ldap): Make use of that option. -- There was no way to specify an LDAPS server in dirmngr_ldapserver.socnf or with gpgsm's --keyserver option. This patch fixes this. Eventually we should allow to replace host and port by a partial URI in the same way ldap_initialize does it. For backward compatibility we do not yet do that. Although the dirmngr code accepts an URL (eg. taken from a certificate), I can't see how the scheme was ever used. Thus the patch also detects an ldaps scheme and uses this. That part has not been tested, though. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
2b9d399cf0
commit
6e1c99bc39
@ -50,6 +50,7 @@ struct ldap_server_s
|
||||
char *user;
|
||||
char *pass;
|
||||
char *base;
|
||||
unsigned int use_ldaps:1;
|
||||
};
|
||||
typedef struct ldap_server_s *ldap_server_t;
|
||||
|
||||
|
@ -123,6 +123,7 @@ enum
|
||||
oDN,
|
||||
oFilter,
|
||||
oAttr,
|
||||
oTls,
|
||||
|
||||
oOnlySearchTimeout,
|
||||
oLogWithPID
|
||||
@ -138,6 +139,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
" a record oriented format")},
|
||||
{ oProxy, "proxy", 2,
|
||||
N_("|NAME|ignore host part and connect through NAME")},
|
||||
{ oTls, "tls", 0, N_("force a TLS connection")},
|
||||
{ oHost, "host", 2, N_("|NAME|connect to host NAME")},
|
||||
{ oPort, "port", 1, N_("|N|connect to port N")},
|
||||
{ oUser, "user", 2, N_("|NAME|use user NAME for authentication")},
|
||||
@ -163,6 +165,7 @@ struct my_opt_s
|
||||
my_ldap_timeval_t timeout;/* Timeout for the LDAP search functions. */
|
||||
unsigned int alarm_timeout; /* And for the alarm based timeout. */
|
||||
int multi;
|
||||
int force_tls;
|
||||
|
||||
estream_t outstream; /* Send output to this stream. */
|
||||
|
||||
@ -287,6 +290,7 @@ ldap_wrapper_main (char **argv, estream_t outstream)
|
||||
myopt->pass = getenv ("DIRMNGR_LDAP_PASS");
|
||||
break;
|
||||
case oProxy: myopt->proxy = pargs.r.ret_str; break;
|
||||
case oTls: myopt->force_tls = 1; break;
|
||||
case oHost: myopt->host = pargs.r.ret_str; break;
|
||||
case oPort: myopt->port = pargs.r.ret_int; break;
|
||||
case oDN: myopt->dn = pargs.r.ret_str; break;
|
||||
@ -622,12 +626,19 @@ fetch_ldap (my_opt_t myopt, const char *url, const LDAPURLDesc *ludp)
|
||||
attrs[1] = NULL;
|
||||
attr = attrs[0];
|
||||
|
||||
if (!port)
|
||||
if (!port && myopt->force_tls)
|
||||
port = 636;
|
||||
else if (!port)
|
||||
port = (ludp->lud_scheme && !strcmp (ludp->lud_scheme, "ldaps"))? 636:389;
|
||||
|
||||
if (myopt->verbose)
|
||||
{
|
||||
log_info (_("processing url '%s'\n"), url);
|
||||
if (myopt->force_tls)
|
||||
log_info ("forcing tls\n");
|
||||
else
|
||||
log_info ("not forcing tls\n");
|
||||
|
||||
if (myopt->user)
|
||||
log_info (_(" user '%s'\n"), myopt->user);
|
||||
if (myopt->pass)
|
||||
@ -665,17 +676,48 @@ fetch_ldap (my_opt_t myopt, const char *url, const LDAPURLDesc *ludp)
|
||||
&& ludp->lud_attrs && ludp->lud_attrs[0] && ludp->lud_attrs[1])
|
||||
log_info (_("WARNING: using first attribute only\n"));
|
||||
|
||||
|
||||
set_timeout (myopt);
|
||||
npth_unprotect ();
|
||||
ld = my_ldap_init (host, port);
|
||||
npth_protect ();
|
||||
if (!ld)
|
||||
|
||||
if (myopt->force_tls
|
||||
|| (ludp->lud_scheme && !strcmp (ludp->lud_scheme, "ldaps")))
|
||||
{
|
||||
log_error (_("LDAP init to '%s:%d' failed: %s\n"),
|
||||
host, port, strerror (errno));
|
||||
return -1;
|
||||
char *uri;
|
||||
|
||||
uri = xtryasprintf ("ldaps://%s:%d", host, port);
|
||||
if (!uri)
|
||||
{
|
||||
log_error (_("error allocating memory: %s\n"),
|
||||
gpg_strerror (gpg_error_from_syserror ()));
|
||||
return -1;
|
||||
}
|
||||
ret = ldap_initialize (&ld, uri);
|
||||
if (ret)
|
||||
{
|
||||
log_error (_("LDAP init to '%s' failed: %s\n"),
|
||||
uri, ldap_err2string (ret));
|
||||
xfree (uri);
|
||||
return -1;
|
||||
}
|
||||
else if (myopt->verbose)
|
||||
log_info (_("LDAP init to '%s' done\n"), uri);
|
||||
xfree (uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep the old way so to avoid regressions. Eventually we
|
||||
* should really consider the supplied scheme and use only
|
||||
* ldap_initialize. */
|
||||
npth_unprotect ();
|
||||
ld = my_ldap_init (host, port);
|
||||
npth_protect ();
|
||||
if (!ld)
|
||||
{
|
||||
log_error (_("LDAP init to '%s:%d' failed: %s\n"),
|
||||
host, port, strerror (errno));
|
||||
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);
|
||||
|
@ -525,7 +525,7 @@ start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context,
|
||||
int argc = 0;
|
||||
int argc_malloced = 0;
|
||||
char portbuf[30], timeoutbuf[30];
|
||||
|
||||
int use_ldaps = 0;
|
||||
|
||||
*context = NULL;
|
||||
|
||||
@ -554,7 +554,7 @@ start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context,
|
||||
goto leave;
|
||||
}
|
||||
base = server->base;
|
||||
|
||||
use_ldaps = server->use_ldaps;
|
||||
}
|
||||
else /* Use a default server. */
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
@ -587,6 +587,8 @@ start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context,
|
||||
argv[argc++] = "--proxy";
|
||||
argv[argc++] = proxy;
|
||||
}
|
||||
if (use_ldaps)
|
||||
argv[argc++] = "--tls";
|
||||
if (host)
|
||||
{
|
||||
argv[argc++] = "--host";
|
||||
|
@ -55,6 +55,7 @@ ldapserver_list_free (ldap_server_t servers)
|
||||
3. field: Username
|
||||
4. field: Password
|
||||
5. field: Base DN
|
||||
6. field: Flags
|
||||
|
||||
FILENAME and LINENO are used for diagnostic purposes only.
|
||||
*/
|
||||
@ -64,9 +65,11 @@ ldapserver_parse_one (char *line,
|
||||
{
|
||||
char *p;
|
||||
char *endp;
|
||||
const char *s;
|
||||
ldap_server_t server;
|
||||
int fieldno;
|
||||
int fail = 0;
|
||||
int i;
|
||||
|
||||
/* Parse the colon separated fields. */
|
||||
server = xcalloc (1, sizeof *server);
|
||||
@ -115,6 +118,32 @@ ldapserver_parse_one (char *line,
|
||||
server->base = xstrdup (p);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
char **flags = NULL;
|
||||
|
||||
flags = strtokenize (p, ",");
|
||||
if (!flags)
|
||||
log_fatal ("strtokenize failed: %s\n",
|
||||
gpg_strerror (gpg_error_from_syserror ()));
|
||||
|
||||
for (i=0; (s = flags[i]); i++)
|
||||
{
|
||||
if (!*s)
|
||||
;
|
||||
else if (!ascii_strcasecmp (s, "ldaps"))
|
||||
server->use_ldaps = 1;
|
||||
else if (!ascii_strcasecmp (s, "ldap"))
|
||||
server->use_ldaps = 0;
|
||||
else
|
||||
log_info (_("%s:%u: ignoring unknown flag '%s'\n"),
|
||||
filename, lineno, s);
|
||||
}
|
||||
|
||||
xfree (flags);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* (We silently ignore extra fields.) */
|
||||
break;
|
||||
|
@ -406,10 +406,14 @@ client for its session. The default value for @var{file} is
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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
|
||||
|
@ -356,13 +356,27 @@ Note that the @command{dirmngr} can in addition be configured with a
|
||||
default list of LDAP servers to be used after those configured with
|
||||
this option. The syntax of @var{string} is:
|
||||
|
||||
@sc{hostname:port:username:password:base_dn}
|
||||
@sc{hostname:port:username:password:base_dn:flags}
|
||||
|
||||
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 all parts of that string are expected to be UTF-8 encoded.
|
||||
This may lead to problems if the @sc{password} has originally been
|
||||
encoded as Latin-1; in such a case better configure this LDAP server
|
||||
encoded as Latin-1; in such a case better configure tsuch an LDAP server
|
||||
using the global configuration of @command{dirmngr}.
|
||||
|
||||
Here is an example which uses the default port, no username, no
|
||||
password, and requests a TLS connection:
|
||||
|
||||
@c man:.RS
|
||||
@example
|
||||
--keyserver ldap.pca.dfn.de::::o=DFN-Verein,c=DE:ldaps
|
||||
@end example
|
||||
@c man:.RE
|
||||
|
||||
|
||||
@item --policy-file @var{filename}
|
||||
@opindex policy-file
|
||||
Change the default name of the policy file to @var{filename}. The
|
||||
|
@ -223,8 +223,9 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
|
||||
char *pass = server->pass ? server->pass : "";
|
||||
char *base = server->base ? server->base : "";
|
||||
|
||||
snprintf (line, DIM (line), "LDAPSERVER %s:%i:%s:%s:%s",
|
||||
server->host, server->port, user, pass, base);
|
||||
snprintf (line, DIM (line), "LDAPSERVER %s:%i:%s:%s:%s:%s",
|
||||
server->host, server->port, user, pass, base,
|
||||
server->use_ldaps? "ldaps":"");
|
||||
|
||||
assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
/* The code below is not required because we don't return an error. */
|
||||
|
36
sm/gpgsm.c
36
sm/gpgsm.c
@ -817,9 +817,17 @@ parse_keyserver_line (char *line,
|
||||
{
|
||||
char *p;
|
||||
char *endp;
|
||||
const char *s;
|
||||
struct keyserver_spec *server;
|
||||
int fieldno;
|
||||
int fail = 0;
|
||||
int i;
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
filename = "[cmd]";
|
||||
lineno = 0;
|
||||
}
|
||||
|
||||
/* Parse the colon separated fields. */
|
||||
server = xcalloc (1, sizeof *server);
|
||||
@ -833,7 +841,7 @@ parse_keyserver_line (char *line,
|
||||
{
|
||||
case 1:
|
||||
if (*p)
|
||||
server->host = xstrdup (p);
|
||||
server->host = xstrdup (p);
|
||||
else
|
||||
{
|
||||
log_error (_("%s:%u: no hostname given\n"),
|
||||
@ -868,6 +876,32 @@ parse_keyserver_line (char *line,
|
||||
server->base = xstrdup (p);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
char **flags = NULL;
|
||||
|
||||
flags = strtokenize (p, ",");
|
||||
if (!flags)
|
||||
log_fatal ("strtokenize failed: %s\n",
|
||||
gpg_strerror (gpg_error_from_syserror ()));
|
||||
|
||||
for (i=0; (s = flags[i]); i++)
|
||||
{
|
||||
if (!*s)
|
||||
;
|
||||
else if (!ascii_strcasecmp (s, "ldaps"))
|
||||
server->use_ldaps = 1;
|
||||
else if (!ascii_strcasecmp (s, "ldap"))
|
||||
server->use_ldaps = 0;
|
||||
else
|
||||
log_info (_("%s:%u: ignoring unknown flag '%s'\n"),
|
||||
filename, lineno, s);
|
||||
}
|
||||
|
||||
xfree (flags);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* (We silently ignore extra fields.) */
|
||||
break;
|
||||
|
@ -48,6 +48,7 @@ struct keyserver_spec
|
||||
char *user;
|
||||
char *pass;
|
||||
char *base;
|
||||
unsigned int use_ldaps:1;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user