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
* 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
* style URI.
* style URI; this can for example be used for hkps or ldap schemes.
*/
gpg_error_t
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->use_tls = 0;
uri->is_http = 0;
uri->is_ldap = 0;
uri->opaque = 0;
uri->v6lit = 0;
uri->onion = 0;
@ -1380,7 +1381,24 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
uri->use_tls = 1;
}
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;
@ -1446,8 +1464,8 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
return GPG_ERR_BAD_URI; /* Hostname includes a Nul. */
p = p2 ? p2 : NULL;
}
else if (uri->is_http)
return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
else if (!no_scheme_check && (uri->is_http || uri->is_ldap))
return GPG_ERR_INV_URI; /* HTTP or LDAP w/o leading double slash. */
else
{
uri->opaque = 1;

View File

@ -51,10 +51,11 @@ struct parsed_uri_s
char *original; /* Unmodified copy of the parsed URI. */
char *scheme; /* Pointer to the scheme string (always lowercase). */
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 opaque:1;/* Unknown scheme; PATH has the rest. */
unsigned int v6lit:1; /* Host was given as a literal v6 address. */
unsigned int onion:1; /* .onion address given. */
unsigned int opaque:1; /* Unknown scheme; PATH has the rest. */
unsigned int v6lit:1; /* Host was given as a literal v6 address. */
unsigned int onion:1; /* .onion address given. */
unsigned int explicit_port :1; /* The port was explicitly specified. */
char *auth; /* username/password for basic auth. */
char *host; /* Host (converted to lowercase). */

View File

@ -308,15 +308,15 @@ ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri)
if(!uri)
err = ks_print_help (ctrl, " ldap");
else if (strcmp (uri->scheme, "ldap") == 0
|| strcmp (uri->scheme, "ldaps") == 0
|| strcmp (uri->scheme, "ldapi") == 0)
else if (uri->is_ldap)
err = ks_print_help (ctrl, data);
else
err = 0;
return err;
}
/* 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

View File

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

View File

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

View File

@ -20,9 +20,13 @@
#include <config.h>
#include "ldap-parse-uri.h"
#include "t-support.h"
#define PGM "t-ldap-parse-uri"
static int verbose;
struct test_ldap_uri_p
{
const char *uri;
@ -32,7 +36,11 @@ struct test_ldap_uri_p
void
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)
{
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;
parsed_uri_t puri;
if (verbose)
fprintf (stderr, PGM ": parsing '%s'\n", test->uri);
err = ldap_parse_uri (&puri, test->uri);
if (err)
{
@ -242,12 +252,48 @@ test_ldap_escape_filter (void)
test_count ++)
check_ldap_escape_filter (test_count, &tests[test_count - 1]);
}
int
main (int argc, char **argv)
{
(void)argc;
(void)argv;
int last_argc = -1;
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_parse_uri ();