+++ /dev/null
-#include <stdio.h>
-
-int itkacl_check(const char * const realm, const char * const user,
- char *errmsg, size_t errmsg_size);
-
-int main()
-{
- char errmsg[1024];
- int ret = itkacl_check("/login/unix-servers/cirkus", "sesse", errmsg, sizeof(errmsg));
-
- if (ret == 0) {
- printf("OK\n");
- } else if (ret == -1) {
- printf("Error: %s\n", errmsg);
- } else {
- printf("Not OK\n");
- }
- return 0;
-}
+++ /dev/null
-#ifndef _ITKACL_H
-#define _ITKACL_H
-
-/*
- * itkacl control library, version 0.1
- *
- * (C) 2004-2009 Steinar H. Gunderson
- * GPL, v2.
- */
-
-int itkacl_check(const char * const realm, const char * const user,
- char *errmsg, size_t errmsg_size);
-
-#endif /* !defined(_ITKACL_H) */
PREFIX=/usr/local
SONAME=libitkacl.so.2
-LIBNAME=libitkacl.so.2.0.0
+LIBNAME=libitkacl.so.2.0.1
all: libitkacl.a $(LIBNAME) itkacl-test
clean:
+itkacl (2.2) unstable; urgency=medium
+
+ * Add an API for keeping a permanent library context, for performance reasons
+ (unbound in buster and newer needs a lot of CU time for creating a new DNS
+ context).
+
+ -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 15 Mar 2022 21:59:20 +0100
+
itkacl (2.1) unstable; urgency=low
* Make the core library support a configuration file (/etc/itkacl.conf),
--- /dev/null
+#include <stdio.h>
+#include "itkacl.h"
+
+int main()
+{
+ char errmsg[1024];
+ int ret;
+ struct itkacl_ctx *ctx;
+
+ ctx = itkacl_create_ctx(errmsg, sizeof(errmsg));
+ if (ctx == NULL) {
+ printf("Error while creating context: %s\n", errmsg);
+ return 1;
+ }
+
+ ret = itkacl_check_with_ctx(ctx, "/login/unix-servers/cirkus", "sesse", errmsg, sizeof(errmsg));
+
+ itkacl_free_ctx(ctx);
+
+ if (ret == 0) {
+ printf("OK\n");
+ } else if (ret == -1) {
+ printf("Error: %s\n", errmsg);
+ } else {
+ printf("Not OK\n");
+ }
+ return 0;
+}
/*
* ITKACL control library.
*
- * (C) 2004-2013 Steinar H. Gunderson
+ * (C) 2004-2022 Steinar H. Gunderson
* GPL, v2.
*/
#include <stdio.h>
#include <ctype.h>
#include <unbound.h>
+#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,
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 /)",
/* 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 */
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;
}
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;
--- /dev/null
+#ifndef _ITKACL_H
+#define _ITKACL_H
+
+/*
+ * itkacl control library, version 2.2
+ *
+ * (C) 2004-2022 Steinar H. Gunderson
+ * GPL, v2.
+ */
+
+int itkacl_check(const char * const realm, const char * const user,
+ char *errmsg, size_t errmsg_size);
+
+/*
+ * Opaque context. A context is created with itkacl_create_ctx()
+ * and freed with itkacl_free_ctx(), and is thread-safe.
+ * If you are making multiple calls to itkacl_check(), it is faster
+ * to reuse the same context over and over (since libunbound can
+ * have rather high setup times depending on configuration).
+ *
+ * Configuration is only reread when the context is created.
+ */
+struct itkacl_ctx;
+
+struct itkacl_ctx *itkacl_create_ctx(char *errmsg, size_t errmsg_size); // Returns NULL on failure.
+void itkacl_free_ctx(struct itkacl_ctx *ctx);
+
+int itkacl_check_with_ctx(struct itkacl_ctx *ctx,
+ const char * const realm, const char * const user,
+ char *errmsg, size_t errmsg_size);
+
+#endif /* !defined(_ITKACL_H) */
+libapache2-mod-authz-itkacl (0.7) unstable; urgency=medium
+
+ * Use the new context system, for increased performance.
+ * No longer depend on obsolete apache2-prefork-dev.
+
+ -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 15 Mar 2022 22:46:53 +0100
+
libapache2-mod-authz-itkacl (0.6) unstable; urgency=medium
* Update to Apache 2.4.
Section: web
Priority: optional
Maintainer: Steinar H. Gunderson <sesse@samfundet.no>
-Build-Depends: debhelper (>= 7.0.0), apache2-prefork-dev, libitkacl-dev, dh-apache2 | apache2-dev
+Build-Depends: debhelper (>= 7.0.0), libitkacl-dev, dh-apache2 | apache2-dev
Standards-Version: 3.9.1
Package: libapache2-mod-authz-itkacl
/*
- * ITKACL module, (C) 2004-2015 Steinar H. Gunderson
+ * ITKACL module, (C) 2004-2022 Steinar H. Gunderson
*/
-#define MODAUTHITKACL_VERSION "0.6"
+#define MODAUTHITKACL_VERSION "0.7"
#include "apr_strings.h"
#include "http_protocol.h"
#include "http_request.h"
#include "mod_auth.h"
+#include "itkacl.h"
module AP_MODULE_DECLARE_DATA authz_itkacl_module;
-
-extern int itkacl_check(const char * const realm, const char * const user,
- char *errmsg, size_t errmsg_size);
+static struct itkacl_ctx *ctx = NULL;
static int handle_require(request_rec *r, const char *username, const char *acl_path)
{
char errmsg[1024];
int ret;
- ret = itkacl_check(acl_path, username, errmsg, 1024);
+ ret = itkacl_check_with_ctx(ctx, acl_path, username, errmsg, 1024);
if (ret == 0) {
return AUTHZ_GRANTED;
}
static int authz_itkacl_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
ap_add_version_component(p, "mod_auth_itkacl/" MODAUTHITKACL_VERSION);
+ if (ctx != NULL) {
+ itkacl_free_ctx(ctx);
+ }
+ {
+ char errmsg[1024];
+ ctx = itkacl_create_ctx(errmsg, sizeof(errmsg));
+ if (ctx == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Error while initializing libitkacl: %s", errmsg);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
return OK;
}
+++ /dev/null
-libitkacl-perl (2.0) unstable; urgency=low
-
- * Initial release.
-
- -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 14 May 2013 01:26:44 +0200
+++ /dev/null
-/* SWIG interface for libitkacl */
-%module itkacl
-
-/* Convert errors to Perl exceptions and keep the interface clean. */
-%inline %{
- extern int itkacl_check(char *realm, char *user, char *errmsg, size_t errmsgsize);
- int check(char *realm, char *user)
- {
- char errmsg[1024];
- int ret = itkacl_check(realm, user, errmsg, 1024);
-
- /* printf("check '%s' vs. '%s' gave %d\n", user, realm, ret); */
- if (ret == -1)
- die(errmsg);
- else
- return (ret == 0);
- }
-
-%}
-
--- /dev/null
+libitkacl-perl (2.2) unstable; urgency=medium
+
+ * Use the new library contexts for higher performance with repeated calls.
+
+ -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 15 Mar 2022 22:24:46 +0100
+
+libitkacl-perl (2.0) unstable; urgency=low
+
+ * Initial release.
+
+ -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 14 May 2013 01:26:44 +0200
--- /dev/null
+/* SWIG interface for libitkacl */
+%module itkacl
+
+%perlcode %{
+_itkacl_init();
+END {
+ _itkacl_deinit();
+}
+
+%}
+
+/* Convert errors to Perl exceptions and keep the interface clean. */
+%inline %{
+ #include "itkacl.h"
+
+ struct itkacl_ctx *_ctx = NULL;
+
+ void _itkacl_init()
+ {
+ char errmsg[1024];
+ _ctx = itkacl_create_ctx(errmsg, sizeof(errmsg));
+ if (_ctx == NULL)
+ die(errmsg);
+ }
+
+ void _itkacl_deinit()
+ {
+ itkacl_free_ctx(_ctx);
+ }
+
+ int check(char *realm, char *user)
+ {
+ char errmsg[1024];
+ int ret = itkacl_check_with_ctx(_ctx, realm, user, errmsg, 1024);
+
+ /* printf("check '%s' vs. '%s' gave %d\n", user, realm, ret); */
+ if (ret == -1)
+ die(errmsg);
+ else
+ return (ret == 0);
+ }
+
+%}
+
+++ /dev/null
-php5-itkacl (2.0) unstable; urgency=low
-
- * Initial release.
-
- -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 14 May 2013 19:02:22 +0200
+++ /dev/null
-etc/php5/conf.d
itkacl_wrap.o: itkacl_wrap.cpp
$(CXX) $(shell php-config --includes) $(CXXFLAGS) -c itkacl_wrap.cpp -o itkacl_wrap.o
-itkacl_wrap.cpp:
- swig -php5 -c++ itkacl.i
+itkacl_wrap.cpp: itkacl.i
+ swig -php7 -noproxy -c++ -cppext cpp itkacl.i
clean:
$(RM) itkacl.php itkacl_wrap.cpp itkacl_wrap.o php_itkacl.h php_itkacl.so
--- /dev/null
+php7-itkacl (2.1) unstable; urgency=medium
+
+ * Port to PHP 7.
+
+ -- Steinar H. Gunderson <sesse@samfundet.no> Fri, 09 Aug 2019 00:05:36 +0200
+
+php5-itkacl (2.0) unstable; urgency=low
+
+ * Initial release.
+
+ -- Steinar H. Gunderson <sesse@samfundet.no> Tue, 14 May 2013 19:02:22 +0200
-Source: php5-itkacl
+Source: php7-itkacl
Priority: extra
Maintainer: Steinar H. Gunderson <sesse@samfundet.no>
-Build-Depends: debhelper (>= 7.0.50~), libitkacl-dev, php5-dev
+Build-Depends: debhelper (>= 7.0.50~), libitkacl-dev, php7.3-dev
Standards-Version: 3.9.1
Section: php
-Package: php5-itkacl
+Package: php7-itkacl
Section: php
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${php:Depends}
--- /dev/null
+etc/php7/conf.d
dh_testroot
dh_prep
dh_installdirs
- $(MAKE) install DESTDIR=debian/php5-itkacl
- install -m 0644 -o root -g root debian/itkacl.ini debian/php5-itkacl/etc/php5/conf.d/
+ $(MAKE) install DESTDIR=debian/php7-itkacl
+ install -m 0644 -o root -g root debian/itkacl.ini debian/php7-itkacl/etc/php7/conf.d/
dh_installdocs
dh_installchangelogs
dh_compress
dh_strip
dh_makeshlibs
dh_shlibdeps
- echo "php:Depends=phpapi-$(shell php-config --phpapi)" >> debian/php5-itkacl.substvars
+ echo "php:Depends=phpapi-$(shell php-config --phpapi)" >> debian/php7-itkacl.substvars
dh_installdeb
dh_gencontrol
dh_md5sums
* restrictions.
*/
%inline %{
- /* This is due to Swig forgetting one file */
- #include <php5/Zend/zend_exceptions.h>
-
extern "C" int itkacl_check(char *realm, char *user, char *errmsg, size_t errmsgsize);
class itkaclwrap {
int ret = itkacl_check(realm, user, itkacl_errmsg, 1024);
if (ret == -1) {
SWIG_exception(SWIG_RuntimeError,itkacl_errmsg);
+thrown: return -1;
} else {
return ret == 0;
}
}
%}
+%pragma(php) code="
+class itkacl {
+ static function check($realm,$user) {
+ return itkaclwrap_check($realm,$user);
+ }
+} "
+