From d9732add3077be74ff7928895587487727cc3894 Mon Sep 17 00:00:00 2001 From: olavmrk Date: Wed, 7 Dec 2011 10:19:40 +0000 Subject: Add checking for AuthContextClassRef - If request miss needed elements AuthnStatement or AuthnContext, HTTP status BadRequest is returned. - If request does not match one of the required AuthnContextClassRef, HTTP status Forbidden is returned. Thanks to Benjamin Dauvergne for implementing this. git-svn-id: https://modmellon.googlecode.com/svn/trunk@141 a716ebb1-153a-0410-b759-cfb97c6a1b53 --- auth_mellon_handler.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'auth_mellon_handler.c') diff --git a/auth_mellon_handler.c b/auth_mellon_handler.c index 1dd96ea..eea0f05 100644 --- a/auth_mellon_handler.c +++ b/auth_mellon_handler.c @@ -1578,6 +1578,59 @@ static int add_attributes(am_cache_entry_t *session, request_rec *r, return OK; } +/* This function validates that the received assertion verify the security level configured by + * MellonAuthnContextClassRef directives + */ +static int am_validate_authn_context_class_ref(request_rec *r, + LassoSaml2Assertion *assertion) { + int i = 0; + LassoSaml2AuthnStatement *authn_statement = NULL; + LassoSaml2AuthnContext *authn_context = NULL; + am_dir_cfg_rec *dir_cfg; + apr_array_header_t *refs; + + dir_cfg = am_get_dir_cfg(r); + refs = dir_cfg->authn_context_class_ref; + if (! refs->nelts) + return OK; + + if (! assertion->AuthnStatement) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Missing AuthnStatement in assertion, returning BadRequest."); + return HTTP_BAD_REQUEST; + } + /* we only consider the first AuthnStatement, I do not know of any idp + * sending more than one. */ + authn_statement = g_list_first(assertion->AuthnStatement)->data; + if (! authn_statement->AuthnContext) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Missing AuthnContext in assertion, returning BadRequest."); + return HTTP_BAD_REQUEST; + } + authn_context = authn_statement->AuthnContext; + if (! authn_context->AuthnContextClassRef) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Missing AuthnContextClassRef in assertion, returning Forbidden."); + return HTTP_FORBIDDEN; + } + for (i = 0; i < refs->nelts; i++) { + const char *ref = ((char **)refs->elts)[i]; + if (strcmp(ref, authn_context->AuthnContextClassRef) == 0) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "AuthnContextClassRef (%s) matches the " + "MellonAuthnContextClassRef directive, " + "access can be granted.", + authn_context->AuthnContextClassRef); + return OK; + } + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "AuthnContextClassRef (%s) does not match the " + "MellonAuthnContextClassRef directive, returning " + "Forbidden.", + authn_context->AuthnContextClassRef); + return HTTP_FORBIDDEN; +} /* This function finishes handling of a login response after it has been parsed * by the HTTP-POST or HTTP-Artifact handler. @@ -1703,6 +1756,13 @@ static int am_handle_reply_common(request_rec *r, LassoLogin *login, } } + /* Check AuthnContextClassRef */ + rc = am_validate_authn_context_class_ref(r, assertion); + if (rc != OK) { + lasso_login_destroy(login); + return rc; + } + /* Create a new session. */ session = am_new_request_session(r); if(session == NULL) { -- cgit