X-Git-Url: https://git.sesse.net/?p=itkacl;a=blobdiff_plain;f=itkacl-2.2%2Fitkacl.c;fp=itkacl-2.1%2Fitkacl.c;h=d7bdfa016c06bc37225628cda3b098f2c62d317a;hp=eda3ebb70dbe00694a87d3d23f0d1abe9b5717e8;hb=55f933b88c9d9992b1ec0ed7c13a621032f7637d;hpb=e51368f580164e7324c706501758aaf56a4fa312 diff --git a/itkacl-2.1/itkacl.c b/itkacl-2.2/itkacl.c similarity index 76% rename from itkacl-2.1/itkacl.c rename to itkacl-2.2/itkacl.c index eda3ebb..d7bdfa0 100644 --- a/itkacl-2.1/itkacl.c +++ b/itkacl-2.2/itkacl.c @@ -1,7 +1,7 @@ /* * ITKACL control library. * - * (C) 2004-2013 Steinar H. Gunderson + * (C) 2004-2022 Steinar H. Gunderson * GPL, v2. */ #include @@ -13,12 +13,19 @@ #include #include +#include "itkacl.h" + struct itkacl_config { char nszone[256]; int require_dnssec; char dnssec_public_key[256]; }; +struct itkacl_ctx { + struct itkacl_config config; + struct ub_ctx *ubctx; +}; + #define CONFIG_FILENAME "/etc/itkacl.conf" static int itkacl_read_config(const char * const filename, @@ -106,18 +113,105 @@ static int itkacl_read_config(const char * const filename, int itkacl_check(const char * const realm, const char * const user, char *errmsg, size_t errmsg_size) { - struct itkacl_config config; + struct itkacl_ctx *ctx; + int err; + + ctx = itkacl_create_ctx(errmsg, errmsg_size); + if (ctx == NULL) { + return -1; + } + + err = itkacl_check_with_ctx(ctx, realm, user, errmsg, errmsg_size); + + itkacl_free_ctx(ctx); + + return err; +} + +struct itkacl_ctx *itkacl_create_ctx(char *errmsg, size_t errmsg_size) +{ + struct itkacl_ctx *ctx; + int ret; + + ctx = (struct itkacl_ctx *)malloc(sizeof(struct itkacl_ctx)); + if (ctx == NULL) { + if (errmsg) + snprintf(errmsg, errmsg_size, "Memory allocation failed"); + return NULL; + } + + if (itkacl_read_config(CONFIG_FILENAME, &ctx->config, errmsg, errmsg_size) != 0) { + free(ctx); + return NULL; + } + + /* Create the DNS resolver context. */ + ctx->ubctx = ub_ctx_create(); + if (ctx->ubctx == NULL) { + if (errmsg) + snprintf(errmsg, errmsg_size, "Host name lookup failure: Could not create DNS context"); + free(ctx); + return NULL; + } + + ret = ub_ctx_resolvconf(ctx->ubctx, NULL); + if (ret != 0) { + if (errmsg) + snprintf(errmsg, errmsg_size, + "Host name lookup failure: Could not read resolv.conf " + "(resolver error: %s) (system error: %s)", + ub_strerror(ret), strerror(errno)); + ub_ctx_delete(ctx->ubctx); + free(ctx); + return NULL; + } + + ret = ub_ctx_hosts(ctx->ubctx, NULL); + if (ret != 0) { + if (errmsg) + snprintf(errmsg, errmsg_size, + "Host name lookup failure: Could not read hosts file " + "(resolver error: %s) (system error: %s)", + ub_strerror(ret), strerror(errno)); + ub_ctx_delete(ctx->ubctx); + free(ctx); + return NULL; + } + + if (strlen(ctx->config.dnssec_public_key) != 0) { + ret = ub_ctx_add_ta_file(ctx->ubctx, 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)", + ctx->config.dnssec_public_key, + ub_strerror(ret), strerror(errno)); + ub_ctx_delete(ctx->ubctx); + free(ctx); + return NULL; + } + } + + return ctx; +} + +void itkacl_free_ctx(struct itkacl_ctx *ctx) +{ + ub_ctx_delete(ctx->ubctx); + free(ctx); +} + +int itkacl_check_with_ctx(struct itkacl_ctx *ctx, + const char * const realm, const char * const user, + char *errmsg, size_t errmsg_size) +{ int ret, nxdomain; const char *ptr; char nszone[256]; char temp[256]; - struct ub_ctx* ctx; struct ub_result* result; - if (itkacl_read_config(CONFIG_FILENAME, &config, errmsg, errmsg_size) != 0) { - return -1; - } - if (realm[0] != '/') { if (errmsg) snprintf(errmsg, errmsg_size, "Invalid realm '%s' (missing leading /)", @@ -155,7 +249,7 @@ int itkacl_check(const char * const realm, const char * const user, /* traverse the realm entry by entry from the root, * creating a DNS zone name as we go */ - strcpy(nszone, config.nszone); + strcpy(nszone, ctx->config.nszone); ptr = realm; while (*ptr) { /* copy all characters to next / or end of string */ @@ -187,57 +281,12 @@ int itkacl_check(const char * const realm, const char * const user, strcpy(temp, nszone); sprintf(nszone, "%s.%s", user, temp); - /* Create the DNS resolver context. */ - ctx = ub_ctx_create(); - if (ctx == NULL) { - if (errmsg) - snprintf(errmsg, errmsg_size, "Host name lookup failure: Could not create DNS context"); - return -1; - } - - ret = ub_ctx_resolvconf(ctx, NULL); - if (ret != 0) { - if (errmsg) - snprintf(errmsg, errmsg_size, - "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, NULL); - if (ret != 0) { - if (errmsg) - snprintf(errmsg, errmsg_size, - "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); + ret = ub_resolve(ctx->ubctx, nszone, 1, 1, &result); if (ret != 0) { if (errmsg) snprintf(errmsg, errmsg_size, "Host name lookup failure: %s", ub_strerror(ret)); - ub_ctx_delete(ctx); return -1; } @@ -247,22 +296,19 @@ int itkacl_check(const char * const realm, const char * const user, 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 (ctx->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); - ub_ctx_delete(ctx); if (nxdomain) return 1;