dirmngr: Rework of the LDAP code, part 1.

* dirmngr/http.h (struct parsed_uri_s): Add flag is_ldap.
* dirmngr/http.c (do_parse_uri): Set flag.  Do not error out for a
missing slashes in an http scheme if NO_SCHEME_CHECK is active.
* dirmngr/t-http.c (main): Print new flag.
* dirmngr/ks-engine-ldap.c (ks_ldap_help): Use flag instead of
checking the scheme.
* dirmngr/ldap-parse-uri.c (ldap_uri_p): Re-implement using
http_parse_uri.
* dirmngr/t-ldap-parse-uri.c (main): Add option --verbose.
--

This patch merely remove the separate parser for checking for an LDAP
scheme.  It is better to let our generic URI parser handle this.  Also
fixes this bug
       || url[4] == 'i' || url[4] == 'i')
to make the rarely used ldapi scheme case-insensitive.

More changes to the LDAP code are planned.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-11-26 13:09:35 +01:00
parent 1009e4e5f7
commit 264c15c72f
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 93 additions and 40 deletions

View File

@ -1292,7 +1292,7 @@ parse_uri (parsed_uri_t *ret_uri, const char *uri,
* On success the caller must use http_release_parsed_uri() to * On success the caller must use http_release_parsed_uri() to
* releases the resources. If NO_SCHEME_CHECK is set, the function * releases the resources. If NO_SCHEME_CHECK is set, the function
* tries to parse the URL in the same way it would do for an HTTP * tries to parse the URL in the same way it would do for an HTTP
* style URI. * style URI; this can for example be used for hkps or ldap schemes.
*/ */
gpg_error_t gpg_error_t
http_parse_uri (parsed_uri_t *ret_uri, const char *uri, http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
@ -1341,6 +1341,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
uri->params = uri->query = NULL; uri->params = uri->query = NULL;
uri->use_tls = 0; uri->use_tls = 0;
uri->is_http = 0; uri->is_http = 0;
uri->is_ldap = 0;
uri->opaque = 0; uri->opaque = 0;
uri->v6lit = 0; uri->v6lit = 0;
uri->onion = 0; uri->onion = 0;
@ -1380,7 +1381,24 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
uri->use_tls = 1; uri->use_tls = 1;
} }
else if (!no_scheme_check) else if (!no_scheme_check)
return GPG_ERR_INV_URI; /* Unsupported scheme */ return GPG_ERR_INV_URI; /* Not an http style scheme. */
else if (!strcmp (uri->scheme, "ldap") && !force_tls)
{
uri->port = 389;
uri->is_ldap = 1;
}
else if (!strcmp (uri->scheme, "ldaps")
|| (force_tls && (!strcmp (uri->scheme, "ldap"))))
{
uri->port = 636;
uri->is_ldap = 1;
uri->use_tls = 1;
}
else if (!strcmp (uri->scheme, "ldapi")) /* LDAP via IPC. */
{
uri->port = 0;
uri->is_ldap = 1;
}
p = p2; p = p2;
@ -1446,8 +1464,8 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
return GPG_ERR_BAD_URI; /* Hostname includes a Nul. */ return GPG_ERR_BAD_URI; /* Hostname includes a Nul. */
p = p2 ? p2 : NULL; p = p2 ? p2 : NULL;
} }
else if (uri->is_http) else if (!no_scheme_check && (uri->is_http || uri->is_ldap))
return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */ return GPG_ERR_INV_URI; /* HTTP or LDAP w/o leading double slash. */
else else
{ {
uri->opaque = 1; uri->opaque = 1;

View File

@ -51,10 +51,11 @@ struct parsed_uri_s
char *original; /* Unmodified copy of the parsed URI. */ char *original; /* Unmodified copy of the parsed URI. */
char *scheme; /* Pointer to the scheme string (always lowercase). */ char *scheme; /* Pointer to the scheme string (always lowercase). */
unsigned int is_http:1; /* This is a HTTP style URI. */ unsigned int is_http:1; /* This is a HTTP style URI. */
unsigned int is_ldap:1; /* This is a LDAP style URI. */
unsigned int use_tls:1; /* Whether TLS should be used. */ unsigned int use_tls:1; /* Whether TLS should be used. */
unsigned int opaque:1;/* Unknown scheme; PATH has the rest. */ unsigned int opaque:1; /* Unknown scheme; PATH has the rest. */
unsigned int v6lit:1; /* Host was given as a literal v6 address. */ unsigned int v6lit:1; /* Host was given as a literal v6 address. */
unsigned int onion:1; /* .onion address given. */ unsigned int onion:1; /* .onion address given. */
unsigned int explicit_port :1; /* The port was explicitly specified. */ unsigned int explicit_port :1; /* The port was explicitly specified. */
char *auth; /* username/password for basic auth. */ char *auth; /* username/password for basic auth. */
char *host; /* Host (converted to lowercase). */ char *host; /* Host (converted to lowercase). */

View File

@ -308,15 +308,15 @@ ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri)
if(!uri) if(!uri)
err = ks_print_help (ctrl, " ldap"); err = ks_print_help (ctrl, " ldap");
else if (strcmp (uri->scheme, "ldap") == 0 else if (uri->is_ldap)
|| strcmp (uri->scheme, "ldaps") == 0
|| strcmp (uri->scheme, "ldapi") == 0)
err = ks_print_help (ctrl, data); err = ks_print_help (ctrl, data);
else else
err = 0; err = 0;
return err; return err;
} }
/* Convert a keyspec to a filter. Return an error if the keyspec is /* Convert a keyspec to a filter. Return an error if the keyspec is
bad or is not supported. The filter is escaped and returned in bad or is not supported. The filter is escaped and returned in

View File

@ -30,37 +30,24 @@
#include "../common/util.h" #include "../common/util.h"
#include "http.h" #include "http.h"
/* Returns 1 if the string is an LDAP URL (begins with ldap:, ldaps: /* Returns 1 if the string is an LDAP URL. */
or ldapi:). */
int int
ldap_uri_p (const char *url) ldap_uri_p (const char *url)
{ {
char *colon = strchr (url, ':'); parsed_uri_t puri;
if (! colon) int result;
return 0;
else
{
int offset = (uintptr_t) colon - (uintptr_t) url;
if (/* All lower case. */ if (http_parse_uri (&puri, url, 1))
(offset == 4 && memcmp (url, "ldap", 4) == 0) result = 0;
|| (offset == 5 else
&& (memcmp (url, "ldaps", 5) == 0 result = !!puri->is_ldap;
&& memcmp (url, "ldapi", 5) == 0))
/* Mixed case. */ http_release_parsed_uri (puri);
|| ((url[0] == 'l' || url[0] == 'L')
&& (url[1] == 'd' || url[1] == 'D') return result;
&& (url[2] == 'a' || url[2] == 'A')
&& (url[3] == 'p' || url[3] == 'P')
&& (url[4] == ':'
|| ((url[4] == 's' || url[4] == 'S'
|| url[4] == 'i' || url[4] == 'i')
&& url[5] == ':'))))
return 1;
return 0;
}
} }
/* Parse a URI and put the result into *purip. On success the /* Parse a URI and put the result into *purip. On success the
caller must use http_release_parsed_uri() to releases the resources. caller must use http_release_parsed_uri() to releases the resources.

View File

@ -419,8 +419,9 @@ main (int argc, char **argv)
} }
putchar ('\n'); putchar ('\n');
} }
printf ("Flags :%s%s%s%s\n", printf ("Flags :%s%s%s%s%s\n",
uri->is_http? " http":"", uri->is_http? " http":"",
uri->is_ldap? " ldap":"",
uri->opaque? " opaque":"", uri->opaque? " opaque":"",
uri->v6lit? " v6lit":"", uri->v6lit? " v6lit":"",
uri->onion? " onion":""); uri->onion? " onion":"");

View File

@ -20,9 +20,13 @@
#include <config.h> #include <config.h>
#include "ldap-parse-uri.h" #include "ldap-parse-uri.h"
#include "t-support.h" #include "t-support.h"
#define PGM "t-ldap-parse-uri"
static int verbose;
struct test_ldap_uri_p struct test_ldap_uri_p
{ {
const char *uri; const char *uri;
@ -32,7 +36,11 @@ struct test_ldap_uri_p
void void
check_ldap_uri_p (int test_count, struct test_ldap_uri_p *test) check_ldap_uri_p (int test_count, struct test_ldap_uri_p *test)
{ {
int result = ldap_uri_p (test->uri); int result;
if (verbose)
fprintf (stderr, PGM ": checking '%s'\n", test->uri);
result = ldap_uri_p (test->uri);
if (result != test->result) if (result != test->result)
{ {
printf ("'%s' is %san LDAP schema, but ldap_uri_p says opposite.\n", printf ("'%s' is %san LDAP schema, but ldap_uri_p says opposite.\n",
@ -106,6 +114,8 @@ check_ldap_parse_uri (int test_count, struct test_ldap_parse_uri *test)
gpg_error_t err; gpg_error_t err;
parsed_uri_t puri; parsed_uri_t puri;
if (verbose)
fprintf (stderr, PGM ": parsing '%s'\n", test->uri);
err = ldap_parse_uri (&puri, test->uri); err = ldap_parse_uri (&puri, test->uri);
if (err) if (err)
{ {
@ -242,12 +252,48 @@ test_ldap_escape_filter (void)
test_count ++) test_count ++)
check_ldap_escape_filter (test_count, &tests[test_count - 1]); check_ldap_escape_filter (test_count, &tests[test_count - 1]);
} }
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
(void)argc; int last_argc = -1;
(void)argv;
if (argc)
{ argc--; argv++; }
while (argc && last_argc != argc )
{
last_argc = argc;
if (!strcmp (*argv, "--"))
{
argc--; argv++;
break;
}
else if (!strcmp (*argv, "--help"))
{
fputs ("usage: " PGM "\n"
"Options:\n"
" --verbose print timings etc.\n",
stdout);
exit (0);
}
else if (!strcmp (*argv, "--verbose"))
{
verbose++;
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2))
{
fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
exit (1);
}
}
if (argc)
{
fprintf (stderr, PGM ": no argumenst are expected\n");
exit (1);
}
test_ldap_uri_p (); test_ldap_uri_p ();
test_ldap_parse_uri (); test_ldap_parse_uri ();