Commit c420c2f3 authored by Christoph Martin's avatar Christoph Martin

Imported Upstream version 1.8.10.1

parents
The primary author of mod_auth_openidc is:
Hans Zandbelt <https://github.com/zandbelt>
Thanks to the following people for contributing to mod_auth_openidc by
reporting bugs, providing fixes, suggesting useful features or other:
Roland Hedberg <https://github.com/rohe>
Bill Simon <https://github.com/billsimon>
Jim Fox <https://github.com/jimfox>
Martin Srom <https://github.com/martinsrom>
Dejan Latinovic <https://github.com/latinovic>
Hiroyuki Wada <https://github.com/wadahiro>
Gunnar Scherf <https://github.com/g10f>
Terrence Fleury <https://github.com/terrencegf>
Jeremy Archer <https://github.com/fatlotus>
Forkbomber <https://github.com/forkbomber>
Kanthi Vaidya <https://github.com/ekanthi>
szakharchenko <https://github.com/szakharchenko>
John Bradley <https://bitbucket.org/ve7jtb>
Stefano Vercelli <https://github.com/steverc>
David Bernick <https://github.com/davidbernick>
Joseph Bester <https://github.com/bester>
Daniel Pfile <https://github.com/pfiled>
Rebecka Gulliksson <https://github.com/rebeckag>
Ryan Kelly <https://github.com/rfk>
John R. Dennis <https://github.com/jdennis>
steve-dave <https://github.com/steve-dave>
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2014-2016 Ping Identity Corporation
* All rights reserved.
*
* Ping Identity Corporation
* 1099 18th St Suite 2950
* Denver, CO 80202
* 303.468.2900
* http://www.pingidentity.com
*
* DISCLAIMER OF WARRANTIES:
*
* THE SOFTWARE PROVIDED HEREUNDER IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
* ANY WARRANTIES OR REPRESENTATIONS EXPRESS, IMPLIED OR STATUTORY; INCLUDING,
* WITHOUT LIMITATION, WARRANTIES OF QUALITY, PERFORMANCE, NONINFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NOR ARE THERE ANY
* WARRANTIES CREATED BY A COURSE OR DEALING, COURSE OF PERFORMANCE OR TRADE
* USAGE. FURTHERMORE, THERE ARE NO WARRANTIES THAT THE SOFTWARE WILL MEET
* YOUR NEEDS OR BE FREE FROM ERRORS, OR THAT THE OPERATION OF THE SOFTWARE
* WILL BE UNINTERRUPTED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
If your looking for binary packages, please see:
https://github.com/pingidentity/mod_auth_openidc/wiki#8-where-can-i-get-binary-packages
and proceed with the Configuration section below.
If your platform is not supported or you want to run the latest code,
you can build from source as described below.
Installation from source
========================
You will require development headers and tools for the following
dependencies:
Apache (>=2.0)
OpenSSL (>=0.9.8) (>=1.0.1 for Elliptic Curve support)
Curl (>=?)
Jansson (>=2.0) (JSON parser for C)
pcre3 (>=?) (Regular Expressions support)
pkg-config
and if you want Redis support:
hiredis (>=0.9.0) (Redis client for C)
Configure, make and install with:
(run ./autogen.sh first if you work straight from the github source tree)
./configure --with-apxs2=/opt/apache2/bin/apxs2
make
make install
Note that, depending on your distribution, apxs2 may be named apxs.
Configuration
=============
Edit the configuration file for your web server. Depending on
your distribution, it may be named '/etc/apache/httpd.conf' or something
different.
You need to add a LoadModule directive for mod_auth_openidc. This will
look similar to this:
LoadModule auth_openidc_module /usr/lib/apache2/modules/mod_auth_openidc.so
To find the full path to mod_auth_openidc.so, you may run:
apxs2 -q LIBEXECDIR
This will print the path where Apache stores modules. mod_auth_openidc.so
will be stored in that directory.
After you have added the LoadModule directive, you must add the configuration
for mod_auth_openidc. For a quickstart doing so, see the provided samples
in the README.md file.
For an exhaustive overview of all configuration primitives, see: auth_openidc.conf
This diff is collapsed.
JWT_SRC = \
src/jose/apr_jwt.c \
src/jose/apr_jwk.c \
src/jose/apr_jws.c \
src/jose/apr_jwe.c
JWT_HDRS = \
src/jose/apr_jose.h
# Source files. mod_auth_openidc.c must be the first file.
SRC=src/mod_auth_openidc.c \
src/cache/file.c \
src/cache/memcache.c \
src/cache/shm.c \
src/cache/lock.c \
src/oauth.c \
src/proto.c \
src/crypto.c \
src/config.c \
src/util.c \
src/authz.c \
src/session.c \
src/metadata.c \
$(JWT_SRC)
ifeq (@HAVE_LIBHIREDIS@, 1)
SRC += \
src/cache/redis.c
REDIS_CFLAGS=-DUSE_LIBHIREDIS @HIREDIS_CFLAGS@
REDIS_LIBS=@HIREDIS_LIBS@
endif
HDRS = \
$(JWT_HDRS) \
src/mod_auth_openidc.h \
src/cache/cache.h
# Files to include when making a .tar.gz-file for distribution
DISTFILES=$(SRC) \
$(HDRS) \
test/test.c \
test/stub.c \
configure \
configure.ac \
Makefile.in \
autogen.sh \
INSTALL \
README.md \
AUTHORS \
DISCLAIMER \
auth_openidc.conf \
LICENSE.txt \
ChangeLog
all: src/mod_auth_openidc.la
CFLAGS=@OPENSSL_CFLAGS@ @CURL_CFLAGS@ @JANSSON_CFLAGS@ @PCRE_CFLAGS@ $(REDIS_CFLAGS)
LIBS=@OPENSSL_LIBS@ @CURL_LIBS@ @JANSSON_LIBS@ @PCRE_LIBS@ $(REDIS_LIBS)
src/mod_auth_openidc.la: $(SRC) $(HDRS)
@APXS2@ @APXS2_OPTS@ -Wc,"-DNAMEVER=\"@NAMEVER@\" $(CFLAGS)" -Wl,"$(LIBS)" -Wc,-Wall -Wc,-g -c $(SRC)
configure: configure.ac
./autogen.sh
@NAMEVER@.tar.gz: $(DISTFILES)
tar -c --transform="s#^#@NAMEVER@/#" -vzf $@ $(DISTFILES)
test/test: test/*.c src/mod_auth_openidc.la
@APXS2@ @APXS2_OPTS@ $(CFLAGS) -Wl,"$(LIBS)" -Isrc -Wc,-Wall -Wc,-g -c -o $@ test/*.c $(SRC:.c=.lo) @APR_LIBS@
test-compile: test/test
test: test-compile
test/test
.PHONY: install
install: src/mod_auth_openidc.la
@APXS2@ @APXS2_OPTS@ -i -n mod_auth_openidc src/mod_auth_openidc.la
.PHONY: distfile
distfile: @NAMEVER@.tar.gz
.PHONY: clean
clean:
rm -f src/mod_auth_openidc.la
rm -f src/*.o src/cache/*.o src/jose/*.o test/*.o
rm -f src/*.lo src/cache/*.lo src/jose/*.lo test/*.lo
rm -f src/*.slo src/cache/*.slo src/jose/*.slo test/*.slo
rm -rf src/.libs/ src/cache/.libs/ src/jose/.libs/ test/.libs
rm -rf test/test
.PHONY: distclean
distclean: clean
rm -f Makefile config.log config.status @NAMEVER@.tar.gz *~ \
build-stamp config.guess config.sub
rm -rf debian/mod-auth_openidc
rm -f debian/files
.PHONY: fullclean
fullclean: distclean
rm -f configure aclocal.m4
This diff is collapsed.
This diff is collapsed.
#!/bin/sh
autoreconf --force --install
rm -rf autom4te.cache/
This diff is collapsed.
AC_INIT([mod_auth_openidc],[1.8.10.1],[hzandbelt@pingidentity.com])
AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION())
# This section defines the --with-apxs2 option.
AC_ARG_WITH(
[apxs2],
[ --with-apxs2=PATH Full path to the apxs2 executable.],
[
APXS2=${withval}
],)
if test "x$APXS2" = "x"; then
# The user didn't specify the --with-apxs2-option.
# Search for apxs2 in the specified directories
AC_PATH_PROG(APXS2, apxs2,,
/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin)
if test "x$APXS2" = "x"; then
# Didn't find apxs2 in any of the specified directories.
# Search for apxs instead.
AC_PATH_PROG(APXS2, apxs,,
/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin)
fi
fi
# Test if $APXS2 exists and is an executable.
if test ! -x "$APXS2"; then
# $APXS2 isn't a executable file.
AC_MSG_ERROR([
Could not find apxs2. Please specify the path to apxs2
using the --with-apxs2=/full/path/to/apxs2 option.
The executable may also be named 'apxs'.
])
fi
# Replace any occurrences of @APXS2@ with the value of $APXS2 in the Makefile.
AC_SUBST(APXS2)
# Use environment varilable APXS2_OPTS to pass params to APXS2 command
AC_ARG_VAR(APXS2_OPTS, [Additional command line options to pass to apxs2.])
# We need the curl library for HTTP callouts.
PKG_CHECK_MODULES(CURL, libcurl)
AC_SUBST(CURL_CFLAGS)
AC_SUBST(CURL_LIBS)
# We need OpenSSL for crypto and HTTPS callouts.
PKG_CHECK_MODULES(OPENSSL, openssl)
AC_SUBST(OPENSSL_CFLAGS)
AC_SUBST(OPENSSL_LIBS)
PKG_CHECK_MODULES(APR, [apr-1, apr-util-1])
AC_SUBST(APR_CFLAGS)
AC_SUBST(APR_LIBS)
# We need Jansson for JSON parsing.
PKG_CHECK_MODULES(JANSSON, jansson)
AC_SUBST(JANSSON_CFLAGS)
AC_SUBST(JANSSON_LIBS)
# PCRE
PKG_CHECK_MODULES(PCRE, libpcre)
AC_SUBST(PCRE_CFLAGS)
AC_SUBST(PCRE_LIBS)
# Redis
AC_ARG_WITH([hiredis],
[AS_HELP_STRING([--with-hiredis],
[support Redis @<:@default=check@:>@])],
[],
[with_hiredis=yes])
AS_CASE(["$with_hiredis"],
[yes], [if test "$HIREDIS_LIBS" == ""; then PKG_CHECK_MODULES([HIREDIS], [hiredis], [HAVE_LIBHIREDIS=1], [HAVE_LIBHIREDIS=0]) ; else [HAVE_LIBHIREDIS=1] ; fi],
[no], [HAVE_LIBHIREDIS=0],
[PKG_CHECK_MODULES([HIREDIS], [hiredis], [HAVE_LIBHIREDIS=1], [HAVE_LIBHIREDIS=0])])
AC_SUBST(HAVE_LIBHIREDIS)
AC_SUBST(HIREDIS_CFLAGS)
AC_SUBST(HIREDIS_LIBS)
# Create Makefile from Makefile.in
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
This diff is collapsed.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/***************************************************************************
* Copyright (C) 2013-2016 Ping Identity Corporation
* All rights reserved.
*
* For further information please contact:
*
* Ping Identity Corporation
* 1099 18th St Suite 2950
* Denver, CO 80202
* 303.468.2900
* http://www.pingidentity.com
*
* DISCLAIMER OF WARRANTIES:
*
* THE SOFTWARE PROVIDED HEREUNDER IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
* ANY WARRANTIES OR REPRESENTATIONS EXPRESS, IMPLIED OR STATUTORY; INCLUDING,
* WITHOUT LIMITATION, WARRANTIES OF QUALITY, PERFORMANCE, NONINFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NOR ARE THERE ANY
* WARRANTIES CREATED BY A COURSE OR DEALING, COURSE OF PERFORMANCE OR TRADE
* USAGE. FURTHERMORE, THERE ARE NO WARRANTIES THAT THE SOFTWARE WILL MEET
* YOUR NEEDS OR BE FREE FROM ERRORS, OR THAT THE OPERATION OF THE SOFTWARE
* WILL BE UNINTERRUPTED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* mem_cache-like interface and semantics (string keys/values) using a storage backend
*
* @Author: Hans Zandbelt - hzandbelt@pingidentity.com
*/
#ifndef _MOD_AUTH_OPENIDC_CACHE_H_
#define _MOD_AUTH_OPENIDC_CACHE_H_
typedef void * (*oidc_cache_cfg_create)(apr_pool_t *pool);
typedef int (*oidc_cache_post_config_function)(server_rec *s);
typedef int (*oidc_cache_child_init_function)(apr_pool_t *p, server_rec *s);
typedef apr_byte_t (*oidc_cache_get_function)(request_rec *r,
const char *section, const char *key, const char **value);
typedef apr_byte_t (*oidc_cache_set_function)(request_rec *r,
const char *section, const char *key, const char *value,
apr_time_t expiry);
typedef int (*oidc_cache_destroy_function)(server_rec *s);
typedef struct oidc_cache_t {
oidc_cache_cfg_create create_config;
oidc_cache_post_config_function post_config;
oidc_cache_child_init_function child_init;
oidc_cache_get_function get;
oidc_cache_set_function set;
oidc_cache_destroy_function destroy;
} oidc_cache_t;
typedef struct oidc_cache_mutex_t {
apr_global_mutex_t *mutex;
char *mutex_filename;
} oidc_cache_mutex_t;
oidc_cache_mutex_t *oidc_cache_mutex_create(apr_pool_t *pool);
apr_byte_t oidc_cache_mutex_post_config(server_rec *s, oidc_cache_mutex_t *m,
const char *type);
apr_status_t oidc_cache_mutex_child_init(apr_pool_t *p, server_rec *s,
oidc_cache_mutex_t *m);
apr_byte_t oidc_cache_mutex_lock(request_rec *r, oidc_cache_mutex_t *m);
apr_byte_t oidc_cache_mutex_unlock(request_rec *r, oidc_cache_mutex_t *m);
apr_byte_t oidc_cache_mutex_destroy(server_rec *s, oidc_cache_mutex_t *m);
extern oidc_cache_t oidc_cache_file;
extern oidc_cache_t oidc_cache_memcache;
extern oidc_cache_t oidc_cache_shm;
#ifdef USE_LIBHIREDIS
extern oidc_cache_t oidc_cache_redis;
#endif
#endif /* _MOD_AUTH_OPENIDC_CACHE_H_ */
This diff is collapsed.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/***************************************************************************
* Copyright (C) 2013-2016 Ping Identity Corporation
* All rights reserved.
*
* For further information please contact:
*
* Ping Identity Corporation
* 1099 18th St Suite 2950
* Denver, CO 80202
* 303.468.2900
* http://www.pingidentity.com
*
* DISCLAIMER OF WARRANTIES:
*
* THE SOFTWARE PROVIDED HEREUNDER IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
* ANY WARRANTIES OR REPRESENTATIONS EXPRESS, IMPLIED OR STATUTORY; INCLUDING,
* WITHOUT LIMITATION, WARRANTIES OF QUALITY, PERFORMANCE, NONINFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NOR ARE THERE ANY
* WARRANTIES CREATED BY A COURSE OR DEALING, COURSE OF PERFORMANCE OR TRADE
* USAGE. FURTHERMORE, THERE ARE NO WARRANTIES THAT THE SOFTWARE WILL MEET
* YOUR NEEDS OR BE FREE FROM ERRORS, OR THAT THE OPERATION OF THE SOFTWARE
* WILL BE UNINTERRUPTED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* global lock implementation
*
* @Author: Hans Zandbelt - hzandbelt@pingidentity.com
*/
#ifndef WIN32
#include <unistd.h>
#endif
#include "apr_general.h"
#include <httpd.h>
#include <http_config.h>
#include <http_log.h>
#ifdef AP_NEED_SET_MUTEX_PERMS
#include "unixd.h"
#endif
#include "../mod_auth_openidc.h"
/* create the cache lock context */
oidc_cache_mutex_t *oidc_cache_mutex_create(apr_pool_t *pool) {
oidc_cache_mutex_t *ctx = apr_pcalloc(pool, sizeof(oidc_cache_mutex_t));
ctx->mutex = NULL;
ctx->mutex_filename = NULL;
return ctx;
}
apr_byte_t oidc_cache_mutex_post_config(server_rec *s, oidc_cache_mutex_t *m,
const char *type) {
apr_status_t rv = APR_SUCCESS;
const char *dir;
/* construct the mutex filename */
apr_temp_dir_get(&dir, s->process->pool);
m->mutex_filename = apr_psprintf(s->process->pool,
"%s/mod_auth_openidc_%s_mutex.%ld.%pp", dir, type,
(long int) getpid(), s);
/* create the mutex lock */
rv = apr_global_mutex_create(&m->mutex, (const char *) m->mutex_filename,
APR_LOCK_DEFAULT, s->process->pool);
if (rv != APR_SUCCESS) {
oidc_serror(s,
"apr_global_mutex_create failed to create mutex on file %s",
m->mutex_filename);
return FALSE;
}
/* need this on Linux */
#ifdef AP_NEED_SET_MUTEX_PERMS
#if MODULE_MAGIC_NUMBER_MAJOR >= 20081201
rv = ap_unixd_set_global_mutex_perms(m->mutex);
#else
rv = unixd_set_global_mutex_perms(m->mutex);
#endif
if (rv != APR_SUCCESS) {
oidc_serror(s,
"unixd_set_global_mutex_perms failed; could not set permissions ");
return FALSE;
}
#endif
return TRUE;
}
/*
* initialize the cache lock in a child process
*/
apr_status_t oidc_cache_mutex_child_init(apr_pool_t *p, server_rec *s,
oidc_cache_mutex_t *m) {
/* initialize the lock for the child process */
apr_status_t rv = apr_global_mutex_child_init(&m->mutex,
(const char *) m->mutex_filename, p);
if (rv != APR_SUCCESS) {
oidc_serror(s,
"apr_global_mutex_child_init failed to reopen mutex on file %s",
m->mutex_filename);
}
return rv;
}
/*
* global lock
*/
apr_byte_t oidc_cache_mutex_lock(request_rec *r, oidc_cache_mutex_t *m) {
apr_status_t rv = apr_global_mutex_lock(m->mutex);
if (rv != APR_SUCCESS) {
oidc_error(r, "apr_global_mutex_lock() failed [%d]", rv);
return FALSE;
}
return TRUE;
}
/*
* global unlock
*/
apr_byte_t oidc_cache_mutex_unlock(request_rec *r, oidc_cache_mutex_t *m) {
apr_status_t rv = apr_global_mutex_unlock(m->mutex);
if (rv != APR_SUCCESS) {
oidc_error(r, "apr_global_mutex_unlock() failed [%d]", rv);
return FALSE;
}
return TRUE;
}
/*
* destroy mutex
*/
apr_byte_t oidc_cache_mutex_destroy(server_rec *s, oidc_cache_mutex_t *m) {
apr_status_t rv = APR_SUCCESS;
if (m->mutex != NULL) {
rv = apr_global_mutex_destroy(m->mutex);
if (rv != APR_SUCCESS) {
oidc_swarn(s, "apr_global_mutex_destroy failed: [%d]", rv);
}
m->mutex = NULL;
}
return rv;
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/***************************************************************************
* Copyright (C) 2013-2016 Ping Identity Corporation
* All rights reserved.
*
* For further information please contact:
*
* Ping Identity Corporation
* 1099 18th St Suite 2950
* Denver, CO 80202
* 303.468.2900
* http://www.pingidentity.com
*
* DISCLAIMER OF WARRANTIES:
*
* THE SOFTWARE PROVIDED HEREUNDER IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
* ANY WARRANTIES OR REPRESENTATIONS EXPRESS, IMPLIED OR STATUTORY; INCLUDING,
* WITHOUT LIMITATION, WARRANTIES OF QUALITY, PERFORMANCE, NONINFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NOR ARE THERE ANY
* WARRANTIES CREATED BY A COURSE OR DEALING, COURSE OF PERFORMANCE OR TRADE
* USAGE. FURTHERMORE, THERE ARE NO WARRANTIES THAT THE SOFTWARE WILL MEET
* YOUR NEEDS OR BE FREE FROM ERRORS, OR THAT THE OPERATION OF THE SOFTWARE
* WILL BE UNINTERRUPTED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* caching using a memcache backend
*
* @Author: Hans Zandbelt - hzandbelt@pingidentity.com
*/
#include "apr_general.h"
#include "apr_strings.h"
#include "apr_hash.h"
#include "apr_memcache.h"
#include <httpd.h>
#include <http_config.h>
#include <http_log.h>
#include "../mod_auth_openidc.h"
// TODO: proper memcache error reporting (server unreachable etc.)
extern module AP_MODULE_DECLARE_DATA auth_openidc_module;
typedef struct oidc_cache_cfg_memcache_t {
/* cache_type = memcache: memcache ptr */
apr_memcache_t *cache_memcache;
} oidc_cache_cfg_memcache_t;
/* create the cache context */
static void *oidc_cache_memcache_cfg_create(apr_pool_t *pool) {
oidc_cache_cfg_memcache_t *context = apr_pcalloc(pool,
sizeof(oidc_cache_cfg_memcache_t));
context->cache_memcache = NULL;
return context;
}
/*
* initialize the memcache struct to a number of memcache servers
*/
static int oidc_cache_memcache_post_config(server_rec *s) {
oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(s->module_config,
&auth_openidc_module);
if (cfg->cache_cfg != NULL)
return APR_SUCCESS;
oidc_cache_cfg_memcache_t *context = oidc_cache_memcache_cfg_create(
s->process->pool);
cfg->cache_cfg = context;
apr_status_t rv = APR_SUCCESS;
int nservers = 0;
char* split;
char* tok;
apr_pool_t *p = s->process->pool;
if (cfg->cache_memcache_servers == NULL) {
oidc_serror(s,
"cache type is set to \"memcache\", but no valid OIDCMemCacheServers setting was found");
return HTTP_INTERNAL_SERVER_ERROR;
}
/* loop over the provided memcache servers to find out the number of servers configured */
char *cache_config = apr_pstrdup(p, cfg->cache_memcache_servers);
split = apr_strtok(cache_config, " ", &tok);
while (split) {
nservers++;
split = apr_strtok(NULL, " ", &tok);
}
/* allocated space for the number of servers */
rv = apr_memcache_create(p, nservers, 0, &context->cache_memcache);
if (rv != APR_SUCCESS) {
oidc_serror(s, "failed to create memcache object of '%d' size",
nservers);
return HTTP_INTERNAL_SERVER_ERROR;
}
/* loop again over the provided servers */
cache_config = apr_pstrdup(p, cfg->cache_memcache_servers);
split = apr_strtok(cache_config, " ", &tok);
while (split) {
apr_memcache_server_t* st;
char* host_str;
char* scope_id;
apr_port_t port;
/* parse out host and port */
rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
if (rv != APR_SUCCESS) {
oidc_serror(s, "failed to parse cache server: '%s'", split);
return HTTP_INTERNAL_SERVER_ERROR;
}
if (host_str == NULL) {
oidc_serror(s,
"failed to parse cache server, no hostname specified: '%s'",
split);
return HTTP_INTERNAL_SERVER_ERROR;
}
if (port == 0)
port = 11211;
/* create the memcache server struct */
// TODO: tune this
rv = apr_memcache_server_create(p, host_str, port, 0, 1, 1, 60, &st);
if (rv != APR_SUCCESS) {
oidc_serror(s, "failed to create cache server: %s:%d", host_str,
port);
return HTTP_INTERNAL_SERVER_ERROR;
}
/* add the memcache server struct to the list */
rv = apr_memcache_add_server(context->cache_memcache, st);
if (rv != APR_SUCCESS) {
oidc_serror(s, "failed to add cache server: %s:%d", host_str, port);
return HTTP_INTERNAL_SERVER_ERROR;