summaryrefslogtreecommitdiff
path: root/www/ap2-auth-mellon
diff options
context:
space:
mode:
authormanu <manu@pkgsrc.org>2011-12-06 09:58:00 +0000
committermanu <manu@pkgsrc.org>2011-12-06 09:58:00 +0000
commitb8c0859d81464063a0d0195cafa4c865a91255ad (patch)
tree9b04c50459dcac527b49f7bcdaec2c9b7fe6841e /www/ap2-auth-mellon
parent45f789517ccfe2504b52a75ff568e4a680dc224e (diff)
downloadpkgsrc-b8c0859d81464063a0d0195cafa4c865a91255ad.tar.gz
Update to mod_auth_mellon 0.4.0 plus upstream patch:
* Honour MellonProbeDiscoveryIdP order when sending probes * Allow MellonUser variable to be translated through MellonSetEnv * A /mellon/probeDisco endpoint replaces the builtin:get-metadata IdP dicovery URL scheme * New MellonCond directive to enable attribute filtering beyond MellonRequire functionalities. * New MellonIdPMetadataGlob directive to load mulitple IdP metadata using a glob(3) pattern. * Support for running behind reverse proxy. * MellonCookieDomain and MellonCookiePath options to configure cookie settings. * Support for loading federation metadata files. * Several bugfixes.
Diffstat (limited to 'www/ap2-auth-mellon')
-rw-r--r--www/ap2-auth-mellon/Makefile12
-rw-r--r--www/ap2-auth-mellon/distinfo15
-rw-r--r--www/ap2-auth-mellon/patches/patch-ac515
-rw-r--r--www/ap2-auth-mellon/patches/patch-ae523
-rw-r--r--www/ap2-auth-mellon/patches/patch-af65
-rw-r--r--www/ap2-auth-mellon/patches/patch-ag149
-rw-r--r--www/ap2-auth-mellon/patches/patch-ah91
-rw-r--r--www/ap2-auth-mellon/patches/patch-ai310
8 files changed, 322 insertions, 1358 deletions
diff --git a/www/ap2-auth-mellon/Makefile b/www/ap2-auth-mellon/Makefile
index 13be9bf71f2..32c31470e54 100644
--- a/www/ap2-auth-mellon/Makefile
+++ b/www/ap2-auth-mellon/Makefile
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.17 2011/05/07 05:15:21 manu Exp $
+# $NetBSD: Makefile,v 1.18 2011/12/06 09:58:01 manu Exp $
#
PKGNAME= ${APACHE_PKG_PREFIX}-${DISTNAME:S/mod_//:S/_/-/}
-DISTNAME= mod_auth_mellon-0.3.0
-PKGREVISION= 3
+DISTNAME= mod_auth_mellon-0.4.0
+PKGREVISION= 1
CATEGORIES= www security
MASTER_SITES= http://modmellon.googlecode.com/files/
@@ -17,6 +17,7 @@ PKG_DESTDIR_SUPPORT= user-destdir
GNU_CONFIGURE= YES
USE_LIBTOOL= YES
USE_TOOLS+= pkg-config
+CFLAGS+= -DLASSO_SERVER_LOAD_METADATA_FLAG_DEFAULT=0
APACHE_MODULE= YES
APACHE_MODULE_NAME= auth_mellon_module
@@ -25,10 +26,10 @@ PKG_APACHE_ACCEPTED= apache22
BUILDLINK_API_DEPENDS.apache+= apache>=2.0.47
SUBST_CLASSES+= pthflags
-SUBST_MESSAGES= Convert -pthread flag to apxs style
+SUBST_MESSAGES= Remove -pthread flag
SUBST_STAGE.pthflags= post-configure
SUBST_FILES.pthflags= Makefile
-SUBST_SED.pthflags= -e 's| -pthread | ${"${PTHREAD_CFLAGS:M-pthread}":?-Wc,-pthread:} ${"${PTHREAD_LDFLAGS:M-pthread}":?-Wl,-pthread:} |g'
+SUBST_SED.pthflags= -e 's| -pthread | |g'
INSTALLATION_DIRS+= lib/httpd
@@ -39,6 +40,7 @@ do-install:
-n auth_mellon mod_auth_mellon.la
.include "../../security/lasso/buildlink3.mk"
+.include "../../mk/pthread.buildlink3.mk"
.include "../../www/curl/buildlink3.mk"
.include "../../mk/bsd.pkg.mk"
diff --git a/www/ap2-auth-mellon/distinfo b/www/ap2-auth-mellon/distinfo
index fa24e895579..8a636760523 100644
--- a/www/ap2-auth-mellon/distinfo
+++ b/www/ap2-auth-mellon/distinfo
@@ -1,11 +1,6 @@
-$NetBSD: distinfo,v 1.10 2011/05/07 05:15:21 manu Exp $
+$NetBSD: distinfo,v 1.11 2011/12/06 09:58:01 manu Exp $
-SHA1 (mod_auth_mellon-0.3.0.tar.gz) = 658dda51652f491552f2ecc84572ed7750f914ff
-RMD160 (mod_auth_mellon-0.3.0.tar.gz) = 69237b1ec266018a86e7134a4662b491af3c261e
-Size (mod_auth_mellon-0.3.0.tar.gz) = 92252 bytes
-SHA1 (patch-ac) = 7976528d9c77b8e30accf60edc958db53ac5e8fb
-SHA1 (patch-ad) = a1bebae20bfbb99bd71d68de19901eaef6c52dbd
-SHA1 (patch-ae) = d51040b6d827940a2c3cf8928dee175efa946e37
-SHA1 (patch-af) = 0803665a14df8582ac20d950a070f73d794b08ea
-SHA1 (patch-ag) = c1ef8704268d99b01d1e96fc2da9be74a7726b9d
-SHA1 (patch-ah) = 6287c038aee79e66539dda12ff447dfd5d9529bf
+SHA1 (mod_auth_mellon-0.4.0.tar.gz) = d09f7bbefe32c2eaa624612584eab1ea8e89820a
+RMD160 (mod_auth_mellon-0.4.0.tar.gz) = 92ef003ae22c43ef81d22f5027486244e76e3d3f
+Size (mod_auth_mellon-0.4.0.tar.gz) = 103708 bytes
+SHA1 (patch-ai) = a7a4f729301bff79cb39d441f9fa48993cdc2899
diff --git a/www/ap2-auth-mellon/patches/patch-ac b/www/ap2-auth-mellon/patches/patch-ac
deleted file mode 100644
index 91a7d3d5b22..00000000000
--- a/www/ap2-auth-mellon/patches/patch-ac
+++ /dev/null
@@ -1,515 +0,0 @@
-$NetBSD: patch-ac,v 1.1 2011/04/04 08:46:42 manu Exp $
-
-Add MellonCond directive (pulled up from upstream)
-
-Index: auth_mellon_util.c
-===================================================================
---- auth_mellon_util.c (revision 113)
-+++ auth_mellon_util.c (working copy)
-@@ -51,7 +51,7 @@
-
-
- /* This function checks if the user has access according
-- * to the MellonRequire directives.
-+ * to the MellonRequire and MellonCond directives.
- *
- * Parameters:
- * request_rec *r The current request.
-@@ -63,51 +63,105 @@
- int am_check_permissions(request_rec *r, am_cache_entry_t *session)
- {
- am_dir_cfg_rec *dir_cfg;
-- apr_hash_index_t *idx;
-- const char *key;
-- apr_array_header_t *rlist;
- int i, j;
-- int rlist_ok;
-- const char **re;
-+ int skip_or = 0;
-
- dir_cfg = am_get_dir_cfg(r);
-
-- /* Iterate over all require-directives. */
-- for(idx = apr_hash_first(r->pool, dir_cfg->require);
-- idx != NULL;
-- idx = apr_hash_next(idx)) {
-+ /* Iterate over all cond-directives */
-+ for (i = 0; i < dir_cfg->cond->nelts; i++) {
-+ am_cond_t *ce;
-+ const char *value = NULL;
-+ int match = 0;
-
-- /* Get current require directive. key will be the name
-- * of the attribute, and rlist is a list of all allowed values.
-+ ce = &((am_cond_t *)(dir_cfg->cond->elts))[i];
-+
-+ /*
-+ * Rule with ignore flog?
- */
-- apr_hash_this(idx, (const void **)&key, NULL, (void **)&rlist);
-+ if (ce->flags & AM_COND_FLAG_IGN)
-+ continue;
-
-- /* Reset status to 0 before search. */
-- rlist_ok = 0;
-+ /*
-+ * We matched a [OR] rule, skip the next rules
-+ * until we have one without [OR].
-+ */
-+ if (skip_or) {
-+ if (!(ce->flags & AM_COND_FLAG_OR))
-+ skip_or = 0;
-
-- re = (const char **)rlist->elts;
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-+ "Skip %s, [OR] rule matched previously",
-+ ce->directive);
-+ continue;
-+ }
-+
-+ /*
-+ * look for a match on each value for this attribute,
-+ * stop on first match.
-+ */
-+ for (j = 0; (j < session->size) && !match; j++) {
-+ const char *varname = NULL;
-
-- /* rlist is an array of all the valid values for this attribute. */
-- for(i = 0; i < rlist->nelts && !rlist_ok; i++) {
-+ /*
-+ * if MAP flag is set, check for remapped
-+ * attribute name with mellonSetEnv
-+ */
-+ if (ce->flags & AM_COND_FLAG_MAP)
-+ varname = apr_hash_get(dir_cfg->envattr,
-+ session->env[j].varname,
-+ APR_HASH_KEY_STRING);
-
-- /* Search for a matching attribute in the session data. */
-- for(j = 0; j < session->size && !rlist_ok; j++) {
-- if(strcmp(session->env[j].varname, key) == 0 &&
-- strcmp(session->env[j].value, re[i]) == 0) {
-- /* We found a attribute with the correct name
-- * and value.
-- */
-- rlist_ok = 1;
-- }
-+ /*
-+ * Otherwise or if not found, use the attribute name
-+ * sent by the IdP.
-+ */
-+ if (varname == NULL)
-+ varname = session->env[j].varname;
-+
-+ if (strcmp(varname, ce->varname) != 0)
-+ continue;
-+
-+ value = session->env[j].value;
-+
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-+ "Evaluate %s vs \"%s\"",
-+ ce->directive, value);
-+
-+ if (value == NULL) {
-+ match = 0; /* can not happen */
-+ } else if (ce->flags & AM_COND_FLAG_REG) {
-+ match = !ap_regexec(ce->regex, value, 0, NULL, 0);
-+ } else if (ce->flags & AM_COND_FLAG_NC) {
-+ match = !strcasecmp(ce->str, value);
-+ } else {
-+ match = !strcmp(ce->str, value);
- }
- }
-
-- if(!rlist_ok) {
-- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
-- "Client failed to match required attribute \"%s\".",
-- key);
-+ if (ce->flags & AM_COND_FLAG_NOT)
-+ match = !match;
-+
-+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-+ "%s: %smatch", ce->directive,
-+ (match == 0) ? "no ": "");
-+
-+ /*
-+ * If no match, we stop here, except if it is an [OR] condition
-+ */
-+ if (!match & !(ce->flags & AM_COND_FLAG_OR)) {
-+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
-+ "Client failed to match %s",
-+ ce->directive);
- return HTTP_FORBIDDEN;
- }
-+
-+ /*
-+ * Match on [OR] condition means we skip until a rule
-+ * without [OR],
-+ */
-+ if (match && (ce->flags & AM_COND_FLAG_OR))
-+ skip_or = 1;
- }
-
- return OK;
-Index: README
-===================================================================
---- README (revision 113)
-+++ README (working copy)
-@@ -152,9 +152,9 @@
- # "auth": We will populate the environment with information about
- # the user if he is authorized. If he is authenticated
- # (logged in), but not authorized (according to the
-- # MellonRequire directives, then we will return a 403
-- # Forbidden error. If he isn't authenticated then we will
-- # redirect him to the login page of the IdP.
-+ # MellonRequire and MellonCond directives, then we will
-+ # return a 403 Forbidden error. If he isn't authenticated
-+ # then we will redirect him to the login page of the IdP.
- #
- # Default: MellonEnable "off"
- MellonEnable "auth"
-@@ -221,14 +221,45 @@
- # Note that the attribute name is the name we received from the
- # IdP.
- #
-- # If you don't list any MellonRequire directives, then any user
-- # authenticated by the IdP will have access to this service. If
-- # you list several MellonRequire directives, then all of them
-- # will have to match.
-+ # If you don't list any MellonRequire directives (and any
-+ # MellonCond directives, see below), then any user authenticated
-+ # by the IdP will have access to this service. If you list several
-+ # MellonRequire directives, then all of them will have to match.
-+ # If you use multiple MellonRequire directive on the same
-+ # attribute, the last overrides the previous ones.
- #
- # Default: None set.
- MellonRequire "eduPersonAffiliation" "student" "employee"
-
-+ # MellonCond provides the same function as MellonRequire, with
-+ # extra functionnality (MellonRequire is retained for backward
-+ # compatibility). The syntax is
-+ # 'MellonCond <attribute name> <value> [<options>]'
-+ #
-+ # <options> is an optional, comma-separated list of option
-+ # encloseed with brackets. Here is an example: [NOT,NC]
-+ # The valid options are:
-+ # OR If this MellonCond evaluted to false, then the
-+ # next one will be checked. If it evalutes to true,
-+ # then the overall check succeeds.
-+ # NOT This MellonCond evaluates to true if the attribute
-+ # does not match the value.
-+ # REG Value to check is a regular expression.
-+ # NC Perform case insensitive match.
-+ # MAP Attempt to search an attribute with name remapped by
-+ # MellonSetEnv. Fallback to non remapped name if not
-+ # found.
-+ #
-+ # It is allowed to have multiple MellonCond on the same
-+ # attribute, and to mix MellonCond and MellonRequire.
-+ # Note that this can create tricky situations, since the OR
-+ # option has effect on a following MellonRequire directive.
-+ #
-+ # Default: none set
-+ # MellonCond "mail" "@example\.net$" [OR,REG]
-+ # MellonCond "mail" "@example\.com$" [OR,REG]
-+ # MellonCond "uid" "superuser"
-+
- # MellonEndpointPath selects which directory mod_auth_mellon
- # should assume contains the SAML 2.0 endpoints. Any request to
- # this directory will be handled by mod_auth_mellon.
-Index: auth_mellon.h
-===================================================================
---- auth_mellon.h (revision 113)
-+++ auth_mellon.h (working copy)
-@@ -124,6 +124,30 @@
- am_decoder_feide,
- } am_decoder_t;
-
-+typedef enum {
-+ AM_COND_FLAG_NULL = 0x00, /* No flags */
-+ AM_COND_FLAG_OR = 0x01, /* Or with next condition */
-+ AM_COND_FLAG_NOT = 0x02, /* Negate this condition */
-+ AM_COND_FLAG_REG = 0x04, /* Condition is regex */
-+ AM_COND_FLAG_NC = 0x08, /* Case insensitive match */
-+ AM_COND_FLAG_MAP = 0x10, /* Try to use attribute name from MellonSetEnv */
-+ AM_COND_FLAG_IGN = 0x20, /* Condition is to be ignored */
-+ AM_COND_FLAG_REQ = 0x40, /* Condition was configure using MellonRequire */
-+} am_cond_flag_t;
-+
-+/* Not counting AM_COND_FLAG_NULL */
-+#define AM_COND_FLAG_COUNT 7
-+
-+extern const char *am_cond_options[];
-+
-+typedef struct {
-+ const char *varname;
-+ int flags;
-+ const char *str;
-+ ap_regex_t *regex;
-+ const char *directive;
-+} am_cond_t;
-+
- typedef struct am_dir_cfg_rec {
- /* enable_mellon is used to enable auth_mellon for a location.
- */
-@@ -136,7 +160,7 @@
-
- const char *varname;
- int secure;
-- apr_hash_t *require;
-+ apr_array_header_t *cond;
- apr_hash_t *envattr;
- const char *userattr;
- const char *idpattr;
-Index: auth_mellon_config.c
-===================================================================
---- auth_mellon_config.c (revision 113)
-+++ auth_mellon_config.c (working copy)
-@@ -422,7 +422,136 @@
- return NULL;
- }
-
-+/* This function decodes MellonCond flags, such as [NOT,REG]
-+ *
-+ * Parameters:
-+ * const char *arg Pointer to the flags string
-+ *
-+ * Returns:
-+ * flags, or -1 on error
-+ */
-+const char *am_cond_options[] = {
-+ "OR", /* AM_EXPIRE_FLAG_OR */
-+ "NOT", /* AM_EXPIRE_FLAG_NOT */
-+ "REG", /* AM_EXPIRE_FLAG_REG */
-+ "NC", /* AM_EXPIRE_FLAG_NC */
-+ "MAP", /* AM_EXPIRE_FLAG_MAP */
-+ "IGN", /* AM_EXPIRE_FLAG_IGN */
-+ "REQ", /* AM_EXPIRE_FLAG_REQ */
-+};
-
-+static int am_cond_flags(const char *arg)
-+{
-+ int flags = AM_COND_FLAG_NULL;
-+
-+ /* Skip inital [ */
-+ if (arg[0] == '[')
-+ arg++;
-+ else
-+ return -1;
-+
-+ do {
-+ apr_size_t i;
-+
-+ for (i = 0; i < AM_COND_FLAG_COUNT; i++) {
-+ apr_size_t optlen = strlen(am_cond_options[i]);
-+
-+ if (strncmp(arg, am_cond_options[i], optlen) == 0) {
-+ /* Make sure we have a separator next */
-+ if (arg[optlen] && !strchr("]\t ,", (int)arg[optlen]))
-+ return -1;
-+
-+ flags |= (1 << i);
-+ arg += optlen;
-+ break;
-+ }
-+
-+ /* no match */
-+ if (i == AM_COND_FLAG_COUNT)
-+ return -1;
-+
-+ /* skip spaces, tabs and commas */
-+ arg += strspn(arg, " \t,");
-+
-+ /* Garbage after ] is ignored */
-+ if (*arg == ']')
-+ return flags;
-+ }
-+ } while (*arg);
-+
-+ /* Missing trailing ] */
-+ return -1;
-+}
-+
-+/* This function handles the MellonCond configuration directive, which
-+ * allows the user to restrict access based on attributes received from
-+ * the IdP.
-+ *
-+ * Parameters:
-+ * cmd_parms *cmd The command structure for the MellonCond
-+ * configuration directive.
-+ * void *struct_ptr Pointer to the current directory configuration.
-+ * const char *attribute Pointer to the attribute name
-+ * const char *value Pointer to the attribute value or regex
-+ * const char *options Pointer to options
-+ *
-+ * Returns:
-+ * NULL on success or an error string on failure.
-+ */
-+static const char *am_set_cond_slot(cmd_parms *cmd,
-+ void *struct_ptr,
-+ const char *attribute,
-+ const char *value,
-+ const char *options)
-+{
-+ am_dir_cfg_rec *d = struct_ptr;
-+ am_cond_t *element;
-+
-+ if (*attribute == '\0' || *value == '\0')
-+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
-+ " takes two or three arguments", NULL);
-+
-+ element = (am_cond_t *)apr_array_push(d->cond);
-+ element->varname = attribute;
-+ element->flags = AM_COND_FLAG_NULL;
-+ element->str = NULL;
-+ element->regex = NULL;
-+ element->directive = apr_pstrcat(cmd->pool, cmd->directive->directive,
-+ " ", cmd->directive->args, NULL);
-+
-+ /* Handle optional flags */
-+ if (*options != '\0') {
-+ int flags;
-+
-+ flags = am_cond_flags(options);
-+ if (flags == -1)
-+ return apr_psprintf(cmd->pool, "%s - invalid flags %s",
-+ cmd->cmd->name, options);
-+
-+ element->flags = flags;
-+ }
-+
-+ if (element->flags & AM_COND_FLAG_REG) {
-+ int regex_flags = AP_REG_EXTENDED|AP_REG_NOSUB;
-+
-+ if (element->flags & AM_COND_FLAG_NC)
-+ regex_flags |= AP_REG_ICASE;
-+
-+ element->regex = ap_pregcomp(cmd->pool, value, regex_flags);
-+ if (element->regex == NULL)
-+ return apr_psprintf(cmd->pool, "%s - invalid regex %s",
-+ cmd->cmd->name, value);
-+ }
-+
-+ /*
-+ * We keep the string also for regex, so that we can
-+ * print it for debug purpose.
-+ */
-+ element->str = value;
-+
-+ return NULL;
-+}
-+
- /* This function handles the MellonRequire configuration directive, which
- * allows the user to restrict access based on attributes received from
- * the IdP.
-@@ -440,10 +569,11 @@
- void *struct_ptr,
- const char *arg)
- {
-- apr_array_header_t *r;
- am_dir_cfg_rec *d = struct_ptr;
- char *attribute, *value;
-- const char **element;
-+ int i;
-+ am_cond_t *element;
-+ am_cond_t *first_element;
-
- attribute = ap_getword_conf(cmd->pool, &arg);
- value = ap_getword_conf(cmd->pool, &arg);
-@@ -453,20 +583,47 @@
- " takes at least two arguments", NULL);
- }
-
-+ /*
-+ * MellonRequire overwrites previous conditions on this attribute
-+ * We just tag the am_cond_t with the ignore flag, as it is
-+ * easier (and probably faster) than to really remove it.
-+ */
-+ for (i = 0; i < d->cond->nelts; i++) {
-+ am_cond_t *ce = &((am_cond_t *)(d->cond->elts))[i];
-+
-+ if ((strcmp(ce->varname, attribute) == 0) &&
-+ (ce->flags & AM_COND_FLAG_REQ))
-+ ce->flags |= AM_COND_FLAG_IGN;
-+ }
-+
-+ first_element = NULL;
- do {
-- r = (apr_array_header_t *)apr_hash_get(d->require, attribute,
-- APR_HASH_KEY_STRING);
-+ element = (am_cond_t *)apr_array_push(d->cond);
-+ element->varname = attribute;
-+ element->flags = AM_COND_FLAG_OR|AM_COND_FLAG_REQ;
-+ element->str = value;
-+ element->regex = NULL;
-
-- if (r == NULL) {
-- r = apr_array_make(cmd->pool, 2, sizeof(const char *));
-- apr_hash_set(d->require, attribute, APR_HASH_KEY_STRING, r);
-+ /*
-+ * When multiple values are given, we track the first one
-+ * in order to retreive the directive
-+ */
-+ if (first_element == NULL) {
-+ element->directive = apr_pstrcat(cmd->pool,
-+ cmd->directive->directive, " ",
-+ cmd->directive->args, NULL);
-+ first_element = element;
-+ } else {
-+ element->directive = first_element->directive;
- }
-
-- element = (const char **)apr_array_push(r);
-- *element = value;
--
- } while (*(value = ap_getword_conf(cmd->pool, &arg)) != '\0');
-
-+ /*
-+ * Remove OR flag on last element
-+ */
-+ element->flags &= ~AM_COND_FLAG_OR;
-+
- return NULL;
- }
-
-@@ -650,6 +807,15 @@
- " for the attribute. The syntax is:"
- " MellonRequire <attribute> <value1> [value2....]."
- ),
-+ AP_INIT_TAKE23(
-+ "MellonCond",
-+ am_set_cond_slot,
-+ NULL,
-+ OR_AUTHCFG,
-+ "Attribute requirements for authorization. Allows you to restrict"
-+ " access based on attributes received from the IdP. The syntax is:"
-+ " MellonRequire <attribute> <value> [<options>]."
-+ ),
- AP_INIT_TAKE1(
- "MellonSessionLength",
- ap_set_int_slot,
-@@ -795,7 +961,7 @@
-
- dir->varname = default_cookie_name;
- dir->secure = default_secure_cookie;
-- dir->require = apr_hash_make(p);
-+ dir->cond = apr_array_make(p, 0, sizeof(am_cond_t));
- dir->envattr = apr_hash_make(p);
- dir->userattr = default_user_attribute;
- dir->idpattr = NULL;
-@@ -871,10 +1037,10 @@
- base_cfg->secure);
-
-
-- new_cfg->require = apr_hash_copy(p,
-- (apr_hash_count(add_cfg->require) > 0) ?
-- add_cfg->require :
-- base_cfg->require);
-+ new_cfg->cond = apr_array_copy(p,
-+ (!apr_is_empty_array(add_cfg->cond)) ?
-+ add_cfg->cond :
-+ base_cfg->cond);
-
- new_cfg->envattr = apr_hash_copy(p,
- (apr_hash_count(add_cfg->envattr) > 0) ?
diff --git a/www/ap2-auth-mellon/patches/patch-ae b/www/ap2-auth-mellon/patches/patch-ae
deleted file mode 100644
index a1f5ba5667f..00000000000
--- a/www/ap2-auth-mellon/patches/patch-ae
+++ /dev/null
@@ -1,523 +0,0 @@
-$NetBSD: patch-ae,v 1.1 2011/04/04 08:46:42 manu Exp $
-
-Replace buildtin: diescovery URL by the discoProbe endpoint (pulled from
-upstream)
-
-Index: auth_mellon_handler.c
-===================================================================
---- auth_mellon_handler.c (revision 112)
-+++ auth_mellon_handler.c (working copy)
-@@ -226,34 +226,7 @@
- return provider_id;
- }
-
--/* This returns built-in IdP discovery timeout
-- *
-- * Parameters:
-- * request_rec *r The request we received.
-- *
-- * Returns:
-- * the timeout, -1 if not enabled.
-- */
--static long am_builtin_discovery_timeout(request_rec *r)
--{
-- am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
-- const char *builtin = "builtin:get-metadata";
-- const char *timeout = "?timeout=";
-- const char *cp;
-- const long default_timeout = 1L;
-
-- if ((cfg->discovery_url == NULL) ||
-- (strncmp(cfg->discovery_url, builtin, strlen(builtin)) != 0))
-- return -1;
--
-- cp = cfg->discovery_url + strlen(builtin);
-- if (strncmp(cp, timeout, strlen(timeout)) != 0)
-- return default_timeout;
--
-- cp += strlen(timeout);
-- return atoi(cp);
--}
--
- /* This function selects an IdP and returns its provider_id
- *
- * Parameters:
-@@ -267,8 +240,6 @@
- am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
- const char *idp_provider_id;
- const char *idp_metadata_file;
-- apr_hash_index_t *index;
-- long timeout;
-
- /*
- * If we have a single IdP, return that one.
-@@ -308,47 +279,6 @@
- return idp_provider_id;
- }
-
-- /*
-- * If built-in IdP discovery is not configured, return default.
-- */
-- timeout = am_builtin_discovery_timeout(r);
-- if (timeout == -1)
-- return am_first_idp(r);
--
-- /*
-- * Otherwise, proceed with built-in IdP discovery:
-- * send probes for all configures IdP to check availability.
-- * The first to answer is chosen. On error, use default.
-- */
-- for (index = apr_hash_first(r->pool, cfg->idp_metadata_files);
-- index;
-- index = apr_hash_next(index)) {
-- void *buffer;
-- apr_size_t len;
-- apr_ssize_t slen;
-- long status;
--
-- apr_hash_this(index,
-- (const void **)&idp_provider_id,
-- &slen,
-- (void *)&idp_metadata_file);
--
-- status = 0;
-- if (am_httpclient_get(r, idp_provider_id, &buffer, &len,
-- timeout, &status) != OK)
-- continue;
--
-- if (status != HTTP_OK) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-- "Cannot probe %s: IdP returned HTTP %ld",
-- idp_provider_id, status);
-- continue;
-- }
--
-- /* We got some succes */
-- return idp_provider_id;
-- }
--
- /*
- * No IdP answered, use default
- * Perhaps we should redirect to an error page instead.
-@@ -2506,7 +2436,6 @@
-
- /* Check if IdP discovery is in use and no IdP was selected yet */
- if ((cfg->discovery_url != NULL) &&
-- (am_builtin_discovery_timeout(r) == -1) && /* no built-in discovery */
- (am_extract_query_parameter(r->pool, r->args, "IdP") == NULL)) {
- char *discovery_url;
- char *return_url;
-@@ -2536,8 +2465,7 @@
- /* If IdP discovery is in use and we have an IdP selected,
- * set the relay_state
- */
-- if ((cfg->discovery_url != NULL) &&
-- (am_builtin_discovery_timeout(r) == -1)) { /* no built-in discovery */
-+ if (cfg->discovery_url != NULL) {
- char *return_url;
-
- return_url = am_extract_query_parameter(r->pool, r->args, "ReturnTo");
-@@ -2615,7 +2543,151 @@
- return am_send_authn_request(r, idp, return_to, is_passive);
- }
-
-+/* This function handles requests to the probe discovery handler
-+ *
-+ * Parameters:
-+ * request_rec *r The request.
-+ *
-+ * Returns:
-+ * OK on success, or an error if any of the steps fail.
-+ */
-+static int am_handle_probe_discovery(request_rec *r) {
-+ am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
-+ const char *idp = NULL;
-+ int timeout;
-+ apr_hash_index_t *index;
-+ char *return_to;
-+ char *idp_param;
-+ char *redirect_url;
-+ int ret;
-
-+ /*
-+ * If built-in IdP discovery is not configured, return error.
-+ * For now we only have the get-metadata metadata method, so this
-+ * information is not saved in configuration nor it is checked here.
-+ */
-+ timeout = cfg->probe_discovery_timeout;
-+ if (timeout == -1) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "probe discovery handler invoked but not "
-+ "configured. Plase set MellonProbeDiscoveryTimeout.");
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+
-+ /*
-+ * Check for mandatory arguments early to avoid sending
-+ * probles for nothing.
-+ */
-+ return_to = am_extract_query_parameter(r->pool, r->args, "return");
-+ if(return_to == NULL) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "Missing required return parameter.");
-+ return HTTP_BAD_REQUEST;
-+ }
-+
-+ ret = am_urldecode(return_to);
-+ if (ret != OK) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, ret, r,
-+ "Could not urldecode return value.");
-+ return HTTP_BAD_REQUEST;
-+ }
-+
-+ idp_param = am_extract_query_parameter(r->pool, r->args, "returnIDParam");
-+ if(idp_param == NULL) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "Missing required returnIDParam parameter.");
-+ return HTTP_BAD_REQUEST;
-+ }
-+
-+ ret = am_urldecode(idp_param);
-+ if (ret != OK) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, ret, r,
-+ "Could not urldecode returnIDParam value.");
-+ return HTTP_BAD_REQUEST;
-+ }
-+
-+ /*
-+ * Proceed with built-in IdP discovery.
-+ *
-+ * Send probes for all configured IdP to check availability.
-+ * The first to answer is chosen, but the list of usable
-+ * IdP can be restricted in configuration.
-+ */
-+ for (index = apr_hash_first(r->pool, cfg->idp_metadata_files);
-+ index;
-+ index = apr_hash_next(index)) {
-+ void *dontcare;
-+ const char *ping_url;
-+ apr_size_t len;
-+ apr_ssize_t slen;
-+ long status;
-+
-+ apr_hash_this(index, (const void **)&idp,
-+ &slen, (void *)&dontcare);
-+ ping_url = idp;
-+
-+ /*
-+ * If a list of IdP was given for probe discovery,
-+ * skip any IdP that does not match.
-+ */
-+ if (apr_hash_count(cfg->probe_discovery_idp) != 0) {
-+ char *value = apr_hash_get(cfg->probe_discovery_idp,
-+ idp, APR_HASH_KEY_STRING);
-+
-+ if (value == NULL) {
-+ /* idp not in list, try the next one */
-+ idp = NULL;
-+ continue;
-+ } else {
-+ /* idp in list, use the value as the ping url */
-+ ping_url = value;
-+ }
-+ }
-+
-+ status = 0;
-+ if (am_httpclient_get(r, ping_url, &dontcare, &len,
-+ timeout, &status) != OK)
-+ continue;
-+
-+ if (status != HTTP_OK) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "Cannot probe %s: \"%s\" returned HTTP %ld",
-+ idp, ping_url, status);
-+ continue;
-+ }
-+
-+ /* We got some succes */
-+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
-+ "probeDiscovery using %s", idp);
-+ break;
-+ }
-+
-+ /*
-+ * On failure, try default
-+ */
-+ if (idp == NULL) {
-+ idp = am_first_idp(r);
-+ if (idp == NULL) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "probeDiscovery found no usable IdP.");
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ } else {
-+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "probeDiscovery "
-+ "failed, trying default IdP %s", idp);
-+ }
-+ }
-+
-+ redirect_url = apr_psprintf(r->pool, "%s%s%s=%s", return_to,
-+ strchr(return_to, '?') ? "&" : "?",
-+ am_urlencode(r->pool, idp_param),
-+ am_urlencode(r->pool, idp));
-+
-+ apr_table_setn(r->headers_out, "Location", redirect_url);
-+
-+ return HTTP_SEE_OTHER;
-+}
-+
-+
- /* This function takes a request for an endpoint and passes it on to the
- * correct handler function.
- *
-@@ -2656,6 +2728,8 @@
- return am_handle_logout(r);
- } else if(!strcmp(endpoint, "login")) {
- return am_handle_login(r);
-+ } else if(!strcmp(endpoint, "probeDisco")) {
-+ return am_handle_probe_discovery(r);
- } else {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Endpoint \"%s\" not handled by mod_auth_mellon.",
-Index: auth_mellon.h
-===================================================================
---- auth_mellon.h (revision 112)
-+++ auth_mellon.h (working copy)
-@@ -174,6 +174,8 @@
-
- /* IdP discovery service */
- const char *discovery_url;
-+ int probe_discovery_timeout;
-+ apr_hash_t *probe_discovery_idp;
-
- /* Mutex to prevent us from creating several lasso server objects. */
- apr_thread_mutex_t *server_mutex;
-Index: README
-===================================================================
---- README (revision 112)
-+++ README (working copy)
-@@ -321,8 +321,17 @@
- # The IdP discovery must redirect the user to the return URL,
- # with retueniDParam set to the selected IdP providerID.
- #
-- # Alternatively, a simple built-in IdP discovery can be used,
-- # by specifying "builtin:get-metadata?timeout=1"
-+ # The builtin:get-metadata discovery URL is not supported anymore
-+ # starting with 0.3.1. See MellonProbeDiscoveryTimeout for
-+ # a replacement.
-+ #
-+ # Default: None set.
-+ MellonDiscoveryURL "http://www.example.net/idp-discovery"
-+
-+ # MellonProbeDiscoveryTimeout sets the timeout of the
-+ # IdP probe discovery service, which is available on the
-+ # probeDisco endoint.
-+ #
- # This will cause the SP to send HTTP GET requests on the
- # configured IdP PorviderID URL. Theses URL should be used to
- # publish metadata, though this is not mandatory. If the IdP
-@@ -330,9 +339,17 @@
- # If the PorviderID URL requires SSL, MellonIdPCAFile is used
- # as a trusted CA bundle.
- #
-- # Default: None set.
-- MellonDiscoveryURL "http://www.example.net/idp-discovery"
-+ # Default: unset, which means the feature is disabled
-+ # MellonProbeDiscoveryTimeout 1
-
-+ # MellonProbeDiscoveryIdP can be used to restrict the
-+ # list of IdP queried by the IdP probe discovery service.
-+ #
-+ # Default unset, which means that all configured IdP are
-+ # queried.
-+ # MellonProbeDiscoveryIdP http://idp1.example.com/saml/metadata
-+ # MellonProbeDiscoveryIdP http://idp2.example.net/saml/metadata
-+
- # This option will make the SAML authentication assertion
- # available in the MELLON_SAML_RESPONSE environement
- # variable. This assertion holds a verifiable signature
-@@ -476,7 +493,39 @@
- This will return the user to "https://www.example.org/logged_out.html"
- after the logout operation has completed.
-
-+===========================================================================
-+ Probe IdP discovery
-+===========================================================================
-
-+mod_auth_mellon has an IdP probe discovery service that sends HTTP GET
-+to IdP and picks the first that answers. This can be used as a poor
-+man's failover setup that redirects to your organisation internal IdP.
-+Here is a sample configuration:
-+
-+ MellonEndpointPath "/saml"
-+ (...)
-+ MellonDiscoveryUrl "/saml/probeDisco"
-+ MellonProbeDiscoveryTimeout 1
-+
-+The SP will sends HTTP GET to each configured IdP providerId URL until
-+it gets an HTTP 200 response within the 1 second timeout. It will then
-+proceed with that IdP.
-+
-+If you are in a federation, then your IdP login page will need to provide
-+an IdP selection feature aimed at users from other institutions (after
-+such a choice, the user would be redirected to the SP's /saml/login
-+endpoint, with ReturnTo and IdP set appropriately). In such a setup,
-+you will want to configure external IdP in mod_auth_mellon, but not
-+use them for IdP probe discovery. The MellonProbeDiscoveryIdP
-+directive can be used to limit the usable IdP for probe discovery:
-+
-+ MellonEndpointPath "/saml"
-+ (...)
-+ MellonDiscoveryUrl "/saml/probeDisco"
-+ MellonProbeDiscoveryTimeout 1
-+ MellonProbeDiscoveryIdP "https://idp1.example.net/saml/metadata"
-+ MellonProbeDiscoveryIdP "https://idp2.example.net/saml/metadata"
-+
- ===========================================================================
- Contributors
- ===========================================================================
-Index: auth_mellon_config.c
-===================================================================
---- auth_mellon_config.c (revision 112)
-+++ auth_mellon_config.c (working copy)
-@@ -76,6 +76,47 @@
- */
- static const int post_count = 100;
-
-+/* This function handles configuration directives which set a
-+ * multivalued string slot in the module configuration (the destination
-+ * strucure is a hash).
-+ *
-+ * Parameters:
-+ * cmd_parms *cmd The command structure for this configuration
-+ * directive.
-+ * void *struct_ptr Pointer to the current directory configuration.
-+ * NULL if we are not in a directory configuration.
-+ * This value isn't used by this function.
-+ * const char *key The string argument following this configuration
-+ * directive in the configuraion file.
-+ * const char *value Optional value to be stored in the hash.
-+ *
-+ * Returns:
-+ * NULL on success or an error string on failure.
-+ */
-+static const char *am_set_hash_string_slot(cmd_parms *cmd,
-+ void *struct_ptr,
-+ const char *key,
-+ const char *value)
-+{
-+ server_rec *s = cmd->server;
-+ apr_pool_t *pconf = s->process->pconf;
-+ am_dir_cfg_rec *cfg = (am_dir_cfg_rec *)struct_ptr;
-+ int offset;
-+ apr_hash_t **hash;
-+
-+ /*
-+ * If no value is given, we just store the key in the hash.
-+ */
-+ if (value == NULL || *value == '\0')
-+ value = key;
-+
-+ offset = (int)(long)cmd->info;
-+ hash = (apr_hash_t **)((char *)cfg + offset);
-+ apr_hash_set(*hash, apr_pstrdup(pconf, key), APR_HASH_KEY_STRING, value);
-+
-+ return NULL;
-+}
-+
- /* This function handles configuration directives which set a file
- * slot in the module configuration. If lasso is recent enough, it
- * attempts to read the file immediatly.
-@@ -133,10 +174,10 @@
- * NULL on success or an error string on failure.
- *
- */
--static const char *am_get_proovider_id(apr_pool_t *p,
-- server_rec *s,
-- const char *file,
-- const char **provider)
-+static const char *am_get_provider_id(apr_pool_t *p,
-+ server_rec *s,
-+ const char *file,
-+ const char **provider)
- {
- char *data;
- apr_xml_parser *xp;
-@@ -195,7 +236,7 @@
- * Returns:
- * NULL on success or an error string on failure.
- */
--static const char *ap_set_idp_string_slot(cmd_parms *cmd,
-+static const char *am_set_idp_string_slot(cmd_parms *cmd,
- void *struct_ptr,
- const char *arg)
- {
-@@ -205,8 +246,8 @@
- const char *error;
- const char *provider_id;
-
-- if ((error = am_get_proovider_id(cmd->pool, s,
-- arg, &provider_id)) != NULL)
-+ if ((error = am_get_provider_id(cmd->pool, s,
-+ arg, &provider_id)) != NULL)
- return apr_psprintf(cmd->pool, "%s - %s", cmd->cmd->name, error);
-
- apr_hash_set(cfg->idp_metadata_files,
-@@ -649,8 +690,8 @@
- ),
- AP_INIT_TAKE1(
- "MellonIdPMetadataFile",
-- ap_set_idp_string_slot,
-- NULL,
-+ am_set_idp_string_slot,
-+ NULL,
- OR_AUTHCFG,
- "Full path to xml metadata file for the IdP."
- ),
-@@ -705,6 +746,21 @@
- "The URL of IdP discovery service. Default is unset."
- ),
- AP_INIT_TAKE1(
-+ "MellonProbeDiscoveryTimeout",
-+ ap_set_int_slot,
-+ (void *)APR_OFFSETOF(am_dir_cfg_rec, probe_discovery_timeout),
-+ OR_AUTHCFG,
-+ "The timeout of IdP probe discovery service. "
-+ "Default is 1s"
-+ ),
-+ AP_INIT_TAKE12(
-+ "MellonProbeDiscoveryIdP",
-+ am_set_hash_string_slot,
-+ (void *)APR_OFFSETOF(am_dir_cfg_rec, probe_discovery_idp),
-+ OR_AUTHCFG,
-+ "An IdP that can be used for IdP probe discovery."
-+ ),
-+ AP_INIT_TAKE1(
- "MellonEndpointPath",
- am_set_endpoint_path,
- NULL,
-@@ -760,6 +816,8 @@
- dir->idp_ca_file = NULL;
- dir->login_path = default_login_path;
- dir->discovery_url = NULL;
-+ dir->probe_discovery_timeout = -1; /* -1 means no probe discovery */
-+ dir->probe_discovery_idp = apr_hash_make(p);
-
- dir->sp_org_name = apr_hash_make(p);
- dir->sp_org_display_name = apr_hash_make(p);
-@@ -903,6 +961,16 @@
- add_cfg->discovery_url :
- base_cfg->discovery_url);
-
-+ new_cfg->probe_discovery_timeout =
-+ (add_cfg->probe_discovery_timeout != -1 ?
-+ add_cfg->probe_discovery_timeout :
-+ base_cfg->probe_discovery_timeout);
-+
-+ new_cfg->probe_discovery_idp = apr_hash_copy(p,
-+ (apr_hash_count(add_cfg->probe_discovery_idp) > 0) ?
-+ add_cfg->probe_discovery_idp :
-+ base_cfg->probe_discovery_idp);
-+
- apr_thread_mutex_create(&new_cfg->server_mutex,
- APR_THREAD_MUTEX_DEFAULT, p);
- new_cfg->server = NULL;
diff --git a/www/ap2-auth-mellon/patches/patch-af b/www/ap2-auth-mellon/patches/patch-af
deleted file mode 100644
index 59bbf9caefb..00000000000
--- a/www/ap2-auth-mellon/patches/patch-af
+++ /dev/null
@@ -1,65 +0,0 @@
-$NetBSD: patch-af,v 1.1 2011/04/04 08:46:42 manu Exp $
-
-Make remapped attribute usable for MellonUser
-
---- auth_mellon_cache.c.orig 2011-02-28 17:12:42.000000000 +0100
-+++ auth_mellon_cache.c 2011-02-28 17:59:02.000000000 +0100
-@@ -367,21 +367,8 @@
- }
- }
- }
-
-- if(t->user[0] != '\0') {
-- /* We have a user-"name". Set r->user and r->ap_auth_type. */
-- r->user = apr_pstrdup(r->pool, t->user);
-- r->ap_auth_type = apr_pstrdup(r->pool, "Mellon");
-- } else {
-- /* We don't have a user-"name". Log error. */
-- ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
-- "Didn't find the attribute \"%s\" in the attributes"
-- " which were received from the IdP. Cannot set a user"
-- " for this request without a valid user attribute.",
-- d->userattr);
-- }
--
- /* Allocate a set of counters for duplicate variables in the list. */
- counters = apr_hash_make(r->pool);
-
- /* Populate the subprocess environment with the attributes we
-@@ -398,8 +385,13 @@
- }
-
- value = t->env[i].value;
-
-+ /*
-+ * If we find a variable remapping to MellonUser, use it.
-+ */
-+ if ((t->user[0] == '\0') && (strcmp(varname, d->userattr) == 0))
-+ strcpy(t->user, value);
-
- /* Find the number of times this variable has been set. */
- count = apr_hash_get(counters, varname, APR_HASH_KEY_STRING);
- if(count == NULL) {
-@@ -425,8 +417,22 @@
- /* Increase the count. */
- ++(*count);
- }
-
-+ if(t->user[0] != '\0') {
-+ /* We have a user-"name". Set r->user and r->ap_auth_type. */
-+ r->user = apr_pstrdup(r->pool, t->user);
-+ r->ap_auth_type = apr_pstrdup(r->pool, "Mellon");
-+ } else {
-+ /* We don't have a user-"name". Log error. */
-+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
-+ "Didn't find the attribute \"%s\" in the attributes"
-+ " which were received from the IdP. Cannot set a user"
-+ " for this request without a valid user attribute.",
-+ d->userattr);
-+ }
-+
-+
- /* Populate with the session? */
- if (d->dump_session) {
- char *session;
- int srclen, dstlen;
diff --git a/www/ap2-auth-mellon/patches/patch-ag b/www/ap2-auth-mellon/patches/patch-ag
deleted file mode 100644
index 8790d1f82f8..00000000000
--- a/www/ap2-auth-mellon/patches/patch-ag
+++ /dev/null
@@ -1,149 +0,0 @@
-$NetBSD: patch-ag,v 1.1 2011/04/04 08:46:42 manu Exp $
-
-Add the MellonIdPMetadataGlob directive (pulled from upstream)
-
-Index: auth_mellon_util.c
-===================================================================
---- auth_mellon_util.c (revision 116)
-+++ auth_mellon_util.c (working copy)
-@@ -838,6 +838,31 @@
- return ret;
- }
-
-+/* This returns the directroy part of a path, a la dirname(3)
-+ *
-+ * Parameters:
-+ * apr_pool_t p Pool to allocate memory from
-+ * const char *path Path to extract directory from
-+ *
-+ * Returns:
-+ * The directory part of path
-+ */
-+const char *am_filepath_dirname(apr_pool_t *p, const char *path)
-+{
-+ char *cp;
-+
-+ /*
-+ * Try Unix and then Windows style. Borrowed from
-+ * apr_match_glob(), it seems it cannot be made more
-+ * portable.
-+ */
-+ if (((cp = strrchr(path, (int)'/')) == NULL) &&
-+ ((cp = strrchr(path, (int)'\\')) == NULL))
-+ return ".";
-+
-+ return apr_pstrndup(p, path, cp - path);
-+}
-+
- /*
- * malloc a buffer and fill it with a given file
- *
-Index: auth_mellon.h
-===================================================================
---- auth_mellon.h (revision 116)
-+++ auth_mellon.h (working copy)
-@@ -52,6 +52,7 @@
- #include "apr_file_io.h"
- #include "apr_xml.h"
- #include "apr_lib.h"
-+#include "apr_fnmatch.h"
-
- #include "ap_config.h"
- #include "httpd.h"
-@@ -296,6 +297,7 @@
- int am_postdir_cleanup(request_rec *s);
- char *am_htmlencode(request_rec *r, const char *str);
- int am_save_post(request_rec *r, const char **relay_state);
-+const char *am_filepath_dirname(apr_pool_t *p, const char *path);
- const char *am_strip_cr(request_rec *r, const char *str);
- const char *am_add_cr(request_rec *r, const char *str);
- const char *am_xstrtok(request_rec *r, const char *str,
-Index: README
-===================================================================
---- README (revision 116)
-+++ README (working copy)
-@@ -349,6 +349,11 @@
- # Default: None set.
- MellonIdPMetadataFile /etc/apache2/mellon/idp-metadata.xml
-
-+ # MellonIdPMetadataGlob is a glob(3) pattern enabled alternative
-+ # to MellonIdPMetadataFile.
-+ # Default: None set.
-+ #MellonIdPMetadataGlob /etc/apache2/mellon/*-metadata.xml
-+
- # MellonIdpPublicKeyFile is the full path of the public key of the
- # IdP. This parameter is optional if the public key is embedded
- # in the IdP's metadata file, or if a certificate authority is
-Index: auth_mellon_config.c
-===================================================================
---- auth_mellon_config.c (revision 116)
-+++ auth_mellon_config.c (working copy)
-@@ -222,6 +222,54 @@
- return NULL;
- }
-
-+/* This function handles configuration directives which use
-+ * a glob pattern
-+ *
-+ * Parameters:
-+ * cmd_parms *cmd The command structure for this configuration
-+ * directive.
-+ * void *struct_ptr Pointer to the current directory configuration.
-+ * NULL if we are not in a directory configuration.
-+ * const char *arg The string argument following this configuration
-+ * directive in the configuraion file.
-+ *
-+ * Returns:
-+ * NULL on success or an error string on failure.
-+ */
-+static const char *am_set_glob_fn(cmd_parms *cmd,
-+ void *struct_ptr,
-+ const char *arg)
-+{
-+ const char *(*take_argv)(cmd_parms *, void *, const char *);
-+ apr_array_header_t *files;
-+ const char *error;
-+ const char *directory;
-+ int i;
-+
-+ take_argv = cmd->info;
-+ directory = am_filepath_dirname(cmd->pool, arg);
-+
-+ if (arg == NULL || *arg == '\0')
-+ return apr_psprintf(cmd->pool, "%s takes one argument", cmd->cmd->name);
-+
-+ if (apr_match_glob(arg, &files, cmd->pool) != 0)
-+ return take_argv(cmd, struct_ptr, arg);
-+
-+ for (i = 0; i < files->nelts; i++) {
-+ const char *path;
-+
-+ path = apr_pstrcat(cmd->pool, directory, "/",
-+ ((const char **)(files->elts))[i], NULL);
-+
-+ error = take_argv(cmd, struct_ptr, path);
-+
-+ if (error != NULL)
-+ return error;
-+ }
-+
-+ return NULL;
-+}
-+
- /* This function handles configuration directives which set an
- * idp related slot in the module configuration.
- *
-@@ -872,6 +920,13 @@
- "Full path to xml metadata file for the IdP."
- ),
- AP_INIT_TAKE1(
-+ "MellonIdPMetadataGlob",
-+ am_set_glob_fn,
-+ am_set_idp_string_slot,
-+ OR_AUTHCFG,
-+ "Full path to xml metadata files for the IdP, with glob(3) patterns."
-+ ),
-+ AP_INIT_TAKE1(
- "MellonIdPPublicKeyFile",
- ap_set_string_slot,
- (void *)APR_OFFSETOF(am_dir_cfg_rec, idp_public_key_file),
diff --git a/www/ap2-auth-mellon/patches/patch-ah b/www/ap2-auth-mellon/patches/patch-ah
deleted file mode 100644
index 03e62cd2e0e..00000000000
--- a/www/ap2-auth-mellon/patches/patch-ah
+++ /dev/null
@@ -1,91 +0,0 @@
-$NetBSD: patch-ah,v 1.1 2011/05/07 05:15:21 manu Exp $
-
-Unbreak SP initiated SLO with lasso >= 2.3.5
-
---- auth_mellon_handler.c.orig 2011-05-07 06:31:46.000000000 +0200
-+++ auth_mellon_handler.c 2011-05-07 06:57:03.000000000 +0200
-@@ -774,8 +774,9 @@
- gint res;
- char *redirect_to;
- LassoProfile *profile;
- LassoSession *session;
-+ GList *assertion_list;
- LassoNode *assertion_n;
- LassoSaml2Assertion *assertion;
- LassoSaml2AuthnStatement *authnStatement;
- LassoSamlp2LogoutRequest *request;
-@@ -822,42 +823,46 @@
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
-
-- /* We need to set the SessionIndex in the LogoutRequest to the
-- * SessionIndex we received during the login operation.
-- */
--
- profile = LASSO_PROFILE(logout);
-- session = lasso_profile_get_session(profile);
-
-- /* We currently only look at the first assertion in the list
-- * lasso_session_get_assertions returns.
-+ /* We need to set the SessionIndex in the LogoutRequest to the SessionIndex
-+ * we received during the login operation. This is not needed since release
-+ * 2.3.0.
- */
-- assertion_n = lasso_session_get_assertions(
-- session, profile->remote_providerID)->data;
-- if(LASSO_IS_SAML2_ASSERTION(assertion_n) == FALSE) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-- "No assertions found for the current session.");
-- lasso_logout_destroy(logout);
-- return HTTP_INTERNAL_SERVER_ERROR;
-- }
--
-- assertion = LASSO_SAML2_ASSERTION(assertion_n);
-+ if (lasso_check_version(2, 3, 0, LASSO_CHECK_VERSION_NUMERIC) == 0) {
-+ session = lasso_profile_get_session(profile);
-+ assertion_list = lasso_session_get_assertions(
-+ session, profile->remote_providerID);
-+ if(! assertion_list ||
-+ LASSO_IS_SAML2_ASSERTION(assertion_list->data) == FALSE) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "No assertions found for the current session.");
-+ lasso_logout_destroy(logout);
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+ /* We currently only look at the first assertion in the list
-+ * lasso_session_get_assertions returns.
-+ */
-+ assertion_n = assertion_list->data;
-
-- /* We assume that the first authnStatement contains the data we want. */
-- authnStatement = LASSO_SAML2_AUTHN_STATEMENT(assertion->AuthnStatement->data);
-+ assertion = LASSO_SAML2_ASSERTION(assertion_n);
-
-- if(!authnStatement) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-- "No AuthnStatement found in the current assertion.");
-- lasso_logout_destroy(logout);
-- return HTTP_INTERNAL_SERVER_ERROR;
-- }
-+ /* We assume that the first authnStatement contains the data we want. */
-+ authnStatement = LASSO_SAML2_AUTHN_STATEMENT(assertion->AuthnStatement->data);
-
-- if(authnStatement->SessionIndex) {
-- request = LASSO_SAMLP2_LOGOUT_REQUEST(profile->request);
-- request->SessionIndex = g_strdup(authnStatement->SessionIndex);
-+ if(!authnStatement) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-+ "No AuthnStatement found in the current assertion.");
-+ lasso_logout_destroy(logout);
-+ return HTTP_INTERNAL_SERVER_ERROR;
-+ }
-+
-+ if(authnStatement->SessionIndex) {
-+ request = LASSO_SAMLP2_LOGOUT_REQUEST(profile->request);
-+ request->SessionIndex = g_strdup(authnStatement->SessionIndex);
-+ }
- }
-
-
- /* Set the RelayState parameter to the return url (if we have one). */
diff --git a/www/ap2-auth-mellon/patches/patch-ai b/www/ap2-auth-mellon/patches/patch-ai
new file mode 100644
index 00000000000..2c89561d992
--- /dev/null
+++ b/www/ap2-auth-mellon/patches/patch-ai
@@ -0,0 +1,310 @@
+$NetBSD: patch-ai,v 1.1 2011/12/06 09:58:01 manu Exp $
+
+Honour MellonProbeDiscoveryIdP order when sending probes (from upstream)
+
+--- auth_mellon.h.orig 2011-05-18 12:39:00.000000000 +0200
++++ auth_mellon.h 2011-12-06 09:54:08.000000000 +0100
+@@ -209,9 +209,9 @@
+
+ /* IdP discovery service */
+ const char *discovery_url;
+ int probe_discovery_timeout;
+- apr_hash_t *probe_discovery_idp;
++ apr_table_t *probe_discovery_idp;
+
+ /* The configuration record we "inherit" the lasso server object from. */
+ struct am_dir_cfg_rec *inherit_server_from;
+ /* Mutex to prevent us from creating several lasso server objects. */
+--- auth_mellon_config.c.orig 2011-05-18 12:39:00.000000000 +0200
++++ auth_mellon_config.c 2011-12-06 09:54:08.000000000 +0100
+@@ -76,8 +76,9 @@
+ * the MellonPostCount configuration directive if you change this.
+ */
+ static const int post_count = 100;
+
++#if unused
+ /* This function handles configuration directives which set a
+ * multivalued string slot in the module configuration (the destination
+ * strucure is a hash).
+ *
+@@ -85,9 +86,8 @@
+ * cmd_parms *cmd The command structure for this configuration
+ * directive.
+ * void *struct_ptr Pointer to the current directory configuration.
+ * NULL if we are not in a directory configuration.
+- * This value isn't used by this function.
+ * const char *key The string argument following this configuration
+ * directive in the configuraion file.
+ * const char *value Optional value to be stored in the hash.
+ *
+@@ -116,8 +116,49 @@
+ apr_hash_set(*hash, apr_pstrdup(pconf, key), APR_HASH_KEY_STRING, value);
+
+ return NULL;
+ }
++#endif /* unused */
++
++/* This function handles configuration directives which set a
++ * multivalued string slot in the module configuration (the destination
++ * strucure is a table).
++ *
++ * Parameters:
++ * cmd_parms *cmd The command structure for this configuration
++ * directive.
++ * void *struct_ptr Pointer to the current directory configuration.
++ * NULL if we are not in a directory configuration.
++ * const char *key The string argument following this configuration
++ * directive in the configuraion file.
++ * const char *value Optional value to be stored in the hash.
++ *
++ * Returns:
++ * NULL on success or an error string on failure.
++ */
++static const char *am_set_table_string_slot(cmd_parms *cmd,
++ void *struct_ptr,
++ const char *key,
++ const char *value)
++{
++ server_rec *s = cmd->server;
++ apr_pool_t *pconf = s->process->pconf;
++ am_dir_cfg_rec *cfg = (am_dir_cfg_rec *)struct_ptr;
++ int offset;
++ apr_table_t **table;
++
++ /*
++ * If no value is given, we just store the key in the hash.
++ */
++ if (value == NULL || *value == '\0')
++ value = key;
++
++ offset = (int)(long)cmd->info;
++ table = (apr_table_t **)((char *)cfg + offset);
++ apr_table_set(*table, apr_pstrdup(pconf, key), value);
++
++ return NULL;
++}
+
+ /* This function handles configuration directives which set a file
+ * slot in the module configuration. If lasso is recent enough, it
+ * attempts to read the file immediatly.
+@@ -1008,9 +1049,9 @@
+ "Default is 1s"
+ ),
+ AP_INIT_TAKE12(
+ "MellonProbeDiscoveryIdP",
+- am_set_hash_string_slot,
++ am_set_table_string_slot,
+ (void *)APR_OFFSETOF(am_dir_cfg_rec, probe_discovery_idp),
+ OR_AUTHCFG,
+ "An IdP that can be used for IdP probe discovery."
+ ),
+@@ -1097,9 +1138,9 @@
+ dir->idp_ignore = NULL;
+ dir->login_path = default_login_path;
+ dir->discovery_url = NULL;
+ dir->probe_discovery_timeout = -1; /* -1 means no probe discovery */
+- dir->probe_discovery_idp = apr_hash_make(p);
++ dir->probe_discovery_idp = apr_table_make(p, 0);
+
+ dir->sp_org_name = apr_hash_make(p);
+ dir->sp_org_display_name = apr_hash_make(p);
+ dir->sp_org_url = apr_hash_make(p);
+@@ -1292,12 +1333,12 @@
+ (add_cfg->probe_discovery_timeout != -1 ?
+ add_cfg->probe_discovery_timeout :
+ base_cfg->probe_discovery_timeout);
+
+- new_cfg->probe_discovery_idp = apr_hash_copy(p,
+- (apr_hash_count(add_cfg->probe_discovery_idp) > 0) ?
+- add_cfg->probe_discovery_idp :
+- base_cfg->probe_discovery_idp);
++ new_cfg->probe_discovery_idp = apr_table_copy(p,
++ (!apr_is_empty_table(add_cfg->probe_discovery_idp)) ?
++ add_cfg->probe_discovery_idp :
++ base_cfg->probe_discovery_idp);
+
+
+ if (cfg_can_inherit_lasso_server(add_cfg)) {
+ new_cfg->inherit_server_from = base_cfg->inherit_server_from;
+--- auth_mellon_handler.c.orig 2011-05-18 12:39:00.000000000 +0200
++++ auth_mellon_handler.c 2011-12-06 10:40:20.000000000 +0100
+@@ -2572,8 +2572,40 @@
+
+ return am_send_authn_request(r, idp, return_to, is_passive);
+ }
+
++/* This function probes an URL (HTTP GET)
++ *
++ * Parameters:
++ * request_rec *r The request.
++ * const char *url The URL
++ * int timeout Timeout in seconds
++ *
++ * Returns:
++ * OK on success, or an error if any of the steps fail.
++ */
++static int am_probe_url(request_rec *r, const char *url, int timeout)
++{
++ void *dontcare;
++ apr_size_t len;
++ long status;
++ int error;
++
++ status = 0;
++ if ((error = am_httpclient_get(r, url, &dontcare, &len,
++ timeout, &status)) != OK)
++ return error;
++
++ if (status != HTTP_OK) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
++ "Probe on \"%s\" returned HTTP %ld",
++ url, status);
++ return status;
++ }
++
++ return OK;
++}
++
+ /* This function handles requests to the probe discovery handler
+ *
+ * Parameters:
+ * request_rec *r The request.
+@@ -2583,11 +2615,10 @@
+ */
+ static int am_handle_probe_discovery(request_rec *r) {
+ am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
+ LassoServer *server;
+- const char *idp = NULL;
++ const char *disco_idp = NULL;
+ int timeout;
+- GHashTableIter iter;
+ char *return_to;
+ char *idp_param;
+ char *redirect_url;
+ int ret;
+@@ -2644,82 +2675,77 @@
+
+ /*
+ * Proceed with built-in IdP discovery.
+ *
+- * Send probes for all configured IdP to check availability.
+- * The first to answer is chosen, but the list of usable
+- * IdP can be restricted in configuration.
++ * First try sending probes to IdP configured for discovery.
++ * Second send probes for all configured IdP
++ * The first to answer is chosen.
++ * If none answer, use the first configured IdP
+ */
+- g_hash_table_iter_init(&iter, server->providers);
+- while (g_hash_table_iter_next(&iter, (void**)&idp, NULL)) {
+- void *dontcare;
+- const char *ping_url;
+- apr_size_t len;
+- long status;
+-
+- ping_url = idp;
+-
+- /*
+- * If a list of IdP was given for probe discovery,
+- * skip any IdP that does not match.
+- */
+- if (apr_hash_count(cfg->probe_discovery_idp) != 0) {
+- char *value = apr_hash_get(cfg->probe_discovery_idp,
+- idp, APR_HASH_KEY_STRING);
+-
+- if (value == NULL) {
+- /* idp not in list, try the next one */
+- continue;
+- } else {
+- /* idp in list, use the value as the ping url */
+- ping_url = value;
++ if (!apr_is_empty_table(cfg->probe_discovery_idp)) {
++ const apr_array_header_t *header;
++ apr_table_entry_t *elts;
++ const char *url;
++ const char *idp;
++ int i;
++
++ header = apr_table_elts(cfg->probe_discovery_idp);
++ elts = (apr_table_entry_t *)header->elts;
++
++ for (i = 0; i < header->nelts; i++) {
++ idp = elts[i].key;
++ url = elts[i].val;
++
++ if (am_probe_url(r, url, timeout) == OK) {
++ disco_idp = idp;
++ break;
+ }
+ }
+-
+- status = 0;
+- if (am_httpclient_get(r, ping_url, &dontcare, &len,
+- timeout, &status) != OK)
+- continue;
+-
+- if (status != HTTP_OK) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+- "Cannot probe %s: \"%s\" returned HTTP %ld",
+- idp, ping_url, status);
+- continue;
++ } else {
++ GList *iter;
++ GList *idp_list;
++ const char *idp;
++
++ idp_list = g_hash_table_get_keys(server->providers);
++ for (iter = idp_list; iter != NULL; iter = iter->next) {
++ idp = iter->data;
++
++ if (am_probe_url(r, idp, timeout) == OK) {
++ disco_idp = idp;
++ break;
++ }
+ }
+-
+- /* We got some succes */
+- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+- "probeDiscovery using %s", idp);
+- break;
++ g_list_free(idp_list);
+ }
+
+ /*
+ * On failure, try default
+ */
+- if (idp == NULL) {
+- idp = am_first_idp(r);
+- if (idp == NULL) {
++ if (disco_idp == NULL) {
++ disco_idp = am_first_idp(r);
++ if (disco_idp == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "probeDiscovery found no usable IdP.");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ } else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "probeDiscovery "
+- "failed, trying default IdP %s", idp);
++ "failed, trying default IdP %s", disco_idp);
+ }
++ } else {
++ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
++ "probeDiscovery using %s", disco_idp);
+ }
+
+ redirect_url = apr_psprintf(r->pool, "%s%s%s=%s", return_to,
+ strchr(return_to, '?') ? "&" : "?",
+ am_urlencode(r->pool, idp_param),
+- am_urlencode(r->pool, idp));
++ am_urlencode(r->pool, disco_idp));
+
+ apr_table_setn(r->headers_out, "Location", redirect_url);
+
+ return HTTP_SEE_OTHER;
+ }
+
+-
+ /* This function takes a request for an endpoint and passes it on to the
+ * correct handler function.
+ *
+ * Parameters: