Add directive MellonSubjectConfirmationDataAddressCheck

MellonSubjectConfirmationDataAddressCheck allows to block client address
checking as given in IdP assertion in the SubjectConfirmationData node,
it can be necessary when client and IdP or SP are in a NAT-ed network or
when the SP is behind a reverse proxy.

git-svn-id: https://modmellon.googlecode.com/svn/trunk/mod_mellon2@152 a716ebb1-153a-0410-b759-cfb97c6a1b53
This commit is contained in:
benjamin.dauvergne 2012-02-17 14:01:24 +00:00
parent fc9faaec9c
commit fd4ad9a744
4 changed files with 41 additions and 1 deletions

7
README
View File

@ -455,6 +455,13 @@ MellonPostCount 100
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos"
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:SoftwarePKI"
# MellonSubjectConfirmationDataAddressCheck is used to control
# the checking of client IP address against the address returned by the
# IdP in Address attribute of the SubjectConfirmationData node. Can be useful if your SP is
# behind a reverse proxy or any kind of strange network topology making IP address of client
# different for the IdP and the SP. Default is on.
# MellonSubjectConfirmationDataAddressCheck On
</Location>

View File

@ -219,6 +219,8 @@ typedef struct am_dir_cfg_rec {
/* AuthnContextClassRef list */
apr_array_header_t *authn_context_class_ref;
/* Controls the checking of SubjectConfirmationData.Address attribute */
int subject_confirmation_data_address_check;
/* Cached lasso server object. */
LassoServer *server;
@ -255,6 +257,26 @@ typedef enum {
extern const command_rec auth_mellon_commands[];
/* When using a value from a directory configuration structure, a special value is used
* to state "inherit" from parent, when reading a value and the value is still inherit from, it
* means that no value has ever been set for this directive, in this case, we use the default
* value.
*
* This macro expects that if your variable is called "name" there is a static const variable named
* "default_name" which holds the default value for this variable.
*/
#define CFG_VALUE(container, name) \
(container->name == inherit_##name ? default_##name : container->name)
#define CFG_MERGE(add_cfg, base_cfg, name) \
(add_cfg->name == inherit_##name ? base_cfg->name : add_cfg->name)
/** Default and inherit value for SubjectConfirmationData Address check setting.
*/
static const int default_subject_confirmation_data_address_check = 1;
static const int inherit_subject_confirmation_data_address_check = -1;
void *auth_mellon_dir_config(apr_pool_t *p, char *d);
void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add);
void *auth_mellon_server_config(apr_pool_t *p, server_rec *s);

View File

@ -1102,6 +1102,13 @@ const command_rec auth_mellon_commands[] = {
"A list of AuthnContextClassRef to request in the AuthnRequest and "
"to validate upon reception of an Assertion"
),
AP_INIT_FLAG(
"MellonSubjectConfirmationDataAddressCheck",
ap_set_flag_slot,
(void *)APR_OFFSETOF(am_dir_cfg_rec, subject_confirmation_data_address_check),
OR_AUTHCFG,
"Check address given in SubjectConfirmationData Address attribute. Default is on."
),
{NULL}
};
@ -1185,6 +1192,7 @@ void *auth_mellon_dir_config(apr_pool_t *p, char *d)
dir->inherit_server_from = dir;
dir->server = NULL;
dir->authn_context_class_ref = apr_array_make(p, 0, sizeof(char *));;
dir->subject_confirmation_data_address_check = inherit_subject_confirmation_data_address_check;
return dir;
}
@ -1391,6 +1399,8 @@ void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add)
add_cfg->authn_context_class_ref :
base_cfg->authn_context_class_ref);
new_cfg->subject_confirmation_data_address_check =
CFG_MERGE(add_cfg, base_cfg, subject_confirmation_data_address_check);
return new_cfg;
}

View File

@ -1150,6 +1150,7 @@ static int am_validate_subject(request_rec *r, LassoSaml2Assertion *assertion,
apr_time_t t;
LassoSaml2SubjectConfirmation *sc;
LassoSaml2SubjectConfirmationData *scd;
am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
if (assertion->Subject == NULL) {
/* No Subject to validate. */
@ -1226,7 +1227,7 @@ static int am_validate_subject(request_rec *r, LassoSaml2Assertion *assertion,
}
}
if (scd->Address) {
if (scd->Address && CFG_VALUE(cfg, subject_confirmation_data_address_check)) {
if (strcasecmp(scd->Address, r->connection->remote_ip)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"Wrong Address in SubjectConfirmationData."