diff --git a/dirmngr/http.c b/dirmngr/http.c index 392c51871..de62edc08 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -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; diff --git a/dirmngr/http.h b/dirmngr/http.h index 01546374e..31e3a880a 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -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). */ diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index d6af26ec4..2a462faa8 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -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 diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c index 94d4efd38..240b98def 100644 --- a/dirmngr/ldap-parse-uri.c +++ b/dirmngr/ldap-parse-uri.c @@ -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. diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 70d7f3fac..8ad5e7a0f 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -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":""); diff --git a/dirmngr/t-ldap-parse-uri.c b/dirmngr/t-ldap-parse-uri.c index 932ca7dcb..984e1412f 100644 --- a/dirmngr/t-ldap-parse-uri.c +++ b/dirmngr/t-ldap-parse-uri.c @@ -20,9 +20,13 @@ #include #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 ();