dirmngr: Rework of the LDAP code, part 1.
authorWerner Koch <wk@gnupg.org>
Tue, 26 Nov 2019 12:09:35 +0000 (13:09 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 26 Nov 2019 12:09:35 +0000 (13:09 +0100)
* 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>
dirmngr/http.c
dirmngr/http.h
dirmngr/ks-engine-ldap.c
dirmngr/ldap-parse-uri.c
dirmngr/t-http.c
dirmngr/t-ldap-parse-uri.c

index 392c518..de62edc 100644 (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;
index 0154637..31e3a88 100644 (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). */
index d6af26e..2a462fa 100644 (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;
 }
+
+
 \f
 /* 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
index 94d4efd..240b98d 100644 (file)
 #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;
+  parsed_uri_t puri;
+  int result;
+
+  if (http_parse_uri (&puri, url, 1))
+    result = 0;
   else
-    {
-      int offset = (uintptr_t) colon - (uintptr_t) url;
-
-      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;
-    }
+    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.
 
index 70d7f3f..8ad5e7a 100644 (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":"");
index 932ca7d..984e141 100644 (file)
 #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]);
 }
+
+
 \f
 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 ();