]> git.sesse.net Git - itkacl/blobdiff - itkacl-2.1/itkacl.c
Use default libunbound paths instead of /etc/resolv.conf and /etc/hosts.
[itkacl] / itkacl-2.1 / itkacl.c
index f1cc09a8639d4c13a7b798051f8acc55e2806bfb..eda3ebb70dbe00694a87d3d23f0d1abe9b5717e8 100644 (file)
@@ -15,6 +15,8 @@
 
 struct itkacl_config {
        char nszone[256];
+       int require_dnssec;
+       char dnssec_public_key[256];
 };
 
 #define CONFIG_FILENAME "/etc/itkacl.conf"
@@ -26,7 +28,10 @@ static int itkacl_read_config(const char * const filename,
        FILE *fp;
        int lineno = 0;
 
+       /* Defaults. */
        strcpy(config->nszone, "");
+       config->require_dnssec = 0;
+       strcpy(config->dnssec_public_key, "");
 
        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;
                }
+               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",
@@ -182,28 +195,42 @@ int itkacl_check(const char * const realm, const char * const user,
                return -1;
        }
 
-       ret = ub_ctx_resolvconf(ctx, "/etc/resolv.conf");
+       ret = ub_ctx_resolvconf(ctx, NULL);
        if (ret != 0) {
                if (errmsg)
                        snprintf(errmsg, errmsg_size,
-                                "Host name lookup failure: Could not read /etc/resolv.conf "
+                                "Host name lookup failure: Could not read resolv.conf "
                                 "(resolver error: %s) (system error: %s)",
                                 ub_strerror(ret), strerror(errno));
                ub_ctx_delete(ctx);
                return -1;
        }
 
-       ret = ub_ctx_hosts(ctx, "/etc/hosts");
+       ret = ub_ctx_hosts(ctx, NULL);
        if (ret != 0) {
                if (errmsg)
                        snprintf(errmsg, errmsg_size,
-                                "Host name lookup failure: Could not read /etc/hosts "
+                                "Host name lookup failure: Could not read hosts file "
                                 "(resolver error: %s) (system error: %s)",
                                 ub_strerror(ret), strerror(errno));
                ub_ctx_delete(ctx);
                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) {
@@ -214,6 +241,24 @@ int itkacl_check(const char * const realm, const char * const user,
                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);