Add DNSSEC support to the core library.
authorSteinar H. Gunderson <sesse@samfundet.no>
Thu, 20 Jun 2013 23:16:58 +0000 (01:16 +0200)
committerSteinar H. Gunderson <sesse@samfundet.no>
Thu, 20 Jun 2013 23:16:58 +0000 (01:16 +0200)
itkacl-2.1/debian/changelog
itkacl-2.1/itkacl.c

index e3b38370f478d628e5f4e910f0a4244f8e0be28f..c9bdedf574adf22c69453066f2b690951d2f480b 100644 (file)
@@ -3,6 +3,7 @@ itkacl (2.1) UNRELEASED; urgency=low
   * Make the core library support a configuration file (/etc/itkacl.conf),
     reading the DNS zone name from there instead of hard-coded it in.
   * Switch to libunbound as the resolver, primarily to get DNSSEC support.
   * Make the core library support a configuration file (/etc/itkacl.conf),
     reading the DNS zone name from there instead of hard-coded it in.
   * Switch to libunbound as the resolver, primarily to get DNSSEC support.
+  * Add DNSSEC support to the core library.
 
  -- Steinar H. Gunderson <sesse@samfundet.no>  Fri, 21 Jun 2013 00:17:34 +0200
 
 
  -- Steinar H. Gunderson <sesse@samfundet.no>  Fri, 21 Jun 2013 00:17:34 +0200
 
index f1cc09a8639d4c13a7b798051f8acc55e2806bfb..2795cf4d6885899058ab740cb436997a9276db5d 100644 (file)
@@ -15,6 +15,8 @@
 
 struct itkacl_config {
        char nszone[256];
 
 struct itkacl_config {
        char nszone[256];
+       int require_dnssec;
+       char dnssec_public_key[256];
 };
 
 #define CONFIG_FILENAME "/etc/itkacl.conf"
 };
 
 #define CONFIG_FILENAME "/etc/itkacl.conf"
@@ -26,7 +28,10 @@ static int itkacl_read_config(const char * const filename,
        FILE *fp;
        int lineno = 0;
 
        FILE *fp;
        int lineno = 0;
 
+       /* Defaults. */
        strcpy(config->nszone, "");
        strcpy(config->nszone, "");
+       config->require_dnssec = 0;
+       strcpy(config->dnssec_public_key, "");
 
        fp = fopen(CONFIG_FILENAME, "r");
        if (fp == NULL) {
 
        fp = fopen(CONFIG_FILENAME, "r");
        if (fp == NULL) {
@@ -70,6 +75,14 @@ static int itkacl_read_config(const char * const filename,
                        strcpy(config->nszone, arg);
                        continue;
                }
                        strcpy(config->nszone, arg);
                        continue;
                }
+               if (strcmp(line, "require-dnssec") == 0) {
+                       config->require_dnssec = 1;
+                       continue;
+               }
+               if (sscanf(line, "dnssec-public-key %255s", arg) == 1) {
+                       strcpy(config->dnssec_public_key, arg);
+                       continue;
+               }
 
                if (errmsg)
                        snprintf(errmsg, errmsg_size, "%s: Could not parse line %d",
 
                if (errmsg)
                        snprintf(errmsg, errmsg_size, "%s: Could not parse line %d",
@@ -204,6 +217,20 @@ int itkacl_check(const char * const realm, const char * const user,
                return -1;
        }
 
                return -1;
        }
 
+       if (strlen(config.dnssec_public_key) != 0) {
+               ret = ub_ctx_add_ta_file(ctx, config.dnssec_public_key);
+               if (ret != 0) {
+                       if (errmsg)
+                               snprintf(errmsg, errmsg_size,
+                                        "Host name lookup failure: Error adding keys from %s "
+                                        "(resolver error: %s) (system error: %s)",
+                                        config.dnssec_public_key,
+                                        ub_strerror(ret), strerror(errno));
+                       ub_ctx_delete(ctx);
+                       return -1;
+               }
+       }
+
        /* Do the actual DNS lookup (TYPE A, CLASS IN). */
        ret = ub_resolve(ctx, nszone, 1, 1, &result);
        if (ret != 0) {
        /* Do the actual DNS lookup (TYPE A, CLASS IN). */
        ret = ub_resolve(ctx, nszone, 1, 1, &result);
        if (ret != 0) {
@@ -214,6 +241,24 @@ int itkacl_check(const char * const realm, const char * const user,
                return -1;
        }
 
                return -1;
        }
 
+       /* Verify DNSSEC. */
+       if (result->bogus) {
+               if (errmsg)
+                       snprintf(errmsg, errmsg_size,
+                                "Host name lookup failure: Bogus DNSSEC result (security failure)");
+               ub_resolve_free(result);
+               ub_ctx_delete(ctx);
+               return -1;
+       }
+       if (config.require_dnssec && !result->secure) {
+               if (errmsg)
+                       snprintf(errmsg, errmsg_size,
+                                "Host name lookup failure: Result was not secured with DNSSEC");
+               ub_resolve_free(result);
+               ub_ctx_delete(ctx);
+               return -1;
+       }
+
        nxdomain = result->nxdomain;
 
        ub_resolve_free(result);
        nxdomain = result->nxdomain;
 
        ub_resolve_free(result);