summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-12-22 18:16:46 +0100
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-12-22 18:16:46 +0100
commitee4058bc221af53b3195639470b43a504402b904 (patch)
treed4b6e63ee12a5ecb788fdacad2a83d508cc2ed79
parent7498143628640ecd5606f2e05457118cb6aaadde (diff)
downloadlasso-ee4058bc221af53b3195639470b43a504402b904.tar.gz
lasso-ee4058bc221af53b3195639470b43a504402b904.tar.xz
lasso-ee4058bc221af53b3195639470b43a504402b904.zip
[saml 2.0] use the new SessionIndex storage for SLO management
It shoulf fix any missing functionnalities regarding missing session indexes in logout requests sent by identity providers or service providers.
-rw-r--r--lasso/saml-2.0/login.c58
-rw-r--r--lasso/saml-2.0/logout.c146
2 files changed, 89 insertions, 115 deletions
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 31343522..7b96868d 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -837,9 +837,16 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
lasso_check_good_rc(lasso_server_saml2_assertion_setup_signature(profile->server,
assertion));
-
/* Encrypt NameID */
if (do_encrypt_nameid) {
+ /* store assertion in session object */
+ if (profile->session == NULL) {
+ profile->session = lasso_session_new();
+ }
+
+ lasso_session_add_assertion(profile->session, profile->remote_providerID,
+ LASSO_NODE(assertion));
+
/* FIXME: as with assertions, it should be possible to setup encryption of NameID for later */
goto_cleanup_if_fail_with_rc(provider != NULL, LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
@@ -860,14 +867,6 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
lasso_provider_get_encryption_sym_key_type(provider));
}
- /* store assertion in session object */
- if (profile->session == NULL) {
- profile->session = lasso_session_new();
- }
-
- lasso_session_add_assertion(profile->session, profile->remote_providerID,
- LASSO_NODE(assertion));
-
response = LASSO_SAMLP2_RESPONSE(profile->response);
lasso_list_add_gobject(response->Assertion, assertion);
lasso_assign_gobject(login->private_data->saml2_assertion, assertion);
@@ -919,6 +918,17 @@ lasso_saml20_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_me
lasso_assign_string(subject_confirmation_data->Recipient, url);
}
+ /* If there is a non-encrypted NameID, fix the assertion in the session */
+ if (assertion && assertion->Subject && assertion->Subject->NameID) {
+ /* store assertion in session object */
+ if (profile->session == NULL) {
+ profile->session = lasso_session_new();
+ }
+ lasso_session_add_assertion(profile->session, profile->remote_providerID,
+ LASSO_NODE(assertion));
+ }
+
+
lasso_check_good_rc(lasso_saml20_profile_build_response_msg(profile, NULL, http_method,
url));
@@ -1334,7 +1344,7 @@ lasso_saml20_login_accept_sso(LassoLogin *login)
{
LassoProfile *profile;
LassoSaml2Assertion *assertion;
- GList *previous_assertions, *t;
+ GList *previous_assertion_ids, *t;
LassoSaml2NameID *ni;
LassoFederation *federation;
@@ -1346,23 +1356,15 @@ lasso_saml20_login_accept_sso(LassoLogin *login)
if (assertion == NULL)
return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
- previous_assertions = lasso_session_get_assertions(profile->session,
+ previous_assertion_ids = lasso_session_get_assertion_ids(profile->session,
profile->remote_providerID);
- for (t = previous_assertions; t; t = g_list_next(t)) {
- LassoSaml2Assertion *ta;
-
- if (LASSO_IS_SAML2_ASSERTION(t->data) == FALSE) {
- continue;
- }
-
- ta = t->data;
-
- if (lasso_strisequal(ta->ID,assertion->ID)) {
- lasso_release_list(previous_assertions);
+ lasso_foreach(t, previous_assertion_ids) {
+ if (lasso_strisequal(t->data, assertion->ID)) {
+ lasso_release_list_of_strings(previous_assertion_ids);
return LASSO_LOGIN_ERROR_ASSERTION_REPLAY;
}
}
- lasso_release_list(previous_assertions);
+ lasso_release_list_of_strings(previous_assertion_ids);
lasso_session_add_assertion(profile->session, profile->remote_providerID,
LASSO_NODE(assertion));
@@ -1425,6 +1427,16 @@ lasso_saml20_login_build_authn_response_msg(LassoLogin *login)
lasso_assign_string(subject_confirmation_data->Recipient, url);
}
+ /* If there is a non-encrypted NameID, fix the assertion in the session */
+ if (assertion && assertion->Subject && assertion->Subject->NameID) {
+ /* store assertion in session object */
+ if (profile->session == NULL) {
+ profile->session = lasso_session_new();
+ }
+ lasso_session_add_assertion(profile->session, profile->remote_providerID,
+ LASSO_NODE(assertion));
+ }
+
switch (login->protocolProfile) {
case LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST:
http_method = LASSO_HTTP_METHOD_POST;
diff --git a/lasso/saml-2.0/logout.c b/lasso/saml-2.0/logout.c
index 8cb9da56..2244d566 100644
--- a/lasso/saml-2.0/logout.c
+++ b/lasso/saml-2.0/logout.c
@@ -34,6 +34,7 @@
#include "../id-ff/sessionprivate.h"
#include "../id-ff/profileprivate.h"
#include "../id-ff/serverprivate.h"
+#include "../id-ff/sessionprivate.h"
#include "../xml/xml_enc.h"
@@ -45,23 +46,15 @@
static void check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile);
-static char*
-_lasso_saml2_assertion_get_session_index(LassoSaml2Assertion *assertion)
-{
- if (! LASSO_IS_SAML2_AUTHN_STATEMENT(assertion->AuthnStatement->data))
- return NULL;
- return((LassoSaml2AuthnStatement*)assertion->AuthnStatement->data)->SessionIndex;
-}
-
int
lasso_saml20_logout_init_request(LassoLogout *logout, LassoProvider *remote_provider,
LassoHttpMethod http_method)
{
LassoProfile *profile = &logout->parent;
- LassoNode *assertion_n = NULL;
- LassoSaml2Assertion *assertion = NULL;
LassoSession *session = NULL;
LassoSamlp2LogoutRequest *logout_request = NULL;
+ GList *name_ids = NULL;
+ LassoSaml2NameID *name_id = NULL;
int rc = 0;
logout_request = (LassoSamlp2LogoutRequest*) lasso_samlp2_logout_request_new();
@@ -75,19 +68,14 @@ lasso_saml20_logout_init_request(LassoLogout *logout, LassoProvider *remote_prov
/* session existence has been checked in id-ff/ */
session = lasso_profile_get_session(profile);
- assertion_n = lasso_session_get_assertion(session, profile->remote_providerID);
- if (LASSO_IS_SAML2_ASSERTION(assertion_n) == FALSE) {
- return critical_error(LASSO_PROFILE_ERROR_MISSING_ASSERTION);
+ name_ids = lasso_session_get_name_ids(session, profile->remote_providerID);
+ if (!name_ids || ! LASSO_IS_SAML2_NAME_ID(name_ids->data)) {
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_ASSERTION);
}
- lasso_ref(assertion_n);
- assertion = (LassoSaml2Assertion*)assertion_n;
+ name_id = name_ids->data; /* take the first */
/* Set the NameID */
- goto_cleanup_if_fail_with_rc(assertion->Subject != NULL,
- LASSO_PROFILE_ERROR_MISSING_SUBJECT);
- goto_cleanup_if_fail_with_rc(assertion->Subject->NameID != NULL,
- LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER);
- lasso_assign_gobject(logout_request->NameID, assertion->Subject->NameID);
+ lasso_assign_gobject(logout_request->NameID, name_id);
/* Encrypt NameID */
if (lasso_provider_get_encryption_mode(remote_provider) == LASSO_ENCRYPTION_MODE_NAMEID) {
@@ -97,17 +85,17 @@ lasso_saml20_logout_init_request(LassoLogout *logout, LassoProvider *remote_prov
}
/* set the session index if one is found */
- lasso_assign_string(logout_request->SessionIndex,
- _lasso_saml2_assertion_get_session_index(assertion));
+ {
+ GList *session_indexes = lasso_session_get_session_indexes(profile->session,
+ remote_provider->ProviderID,
+ &name_id->parent);
+ lasso_samlp2_logout_request_set_session_indexes(logout_request, session_indexes);
+ lasso_release_list_of_strings(session_indexes);
+ }
cleanup:
- /* all is going well, remove the assertion */
- if (rc == 0) {
- lasso_session_remove_assertion(session,
- profile->remote_providerID);
- }
+ lasso_release_list_of_gobjects(name_ids);
lasso_release_gobject(logout_request);
- lasso_release_gobject(assertion_n);
return rc;
}
@@ -152,26 +140,25 @@ cleanup:
int
lasso_saml20_logout_validate_request(LassoLogout *logout)
{
- LassoProfile *profile = LASSO_PROFILE(logout);
- LassoProvider *remote_provider;
- LassoSamlp2StatusResponse *response;
- LassoSaml2NameID *name_id;
- LassoNode *assertion_n;
- LassoSaml2Assertion *assertion;
- LassoSamlp2LogoutRequest *logout_request;
+ LassoProfile *profile = &logout->parent;
+ LassoProvider *remote_provider = NULL;
+ LassoSamlp2StatusResponse *response = NULL;
+ LassoSaml2NameID *name_id = NULL;
+ LassoSamlp2LogoutRequest *logout_request = NULL;
+ GList *local_session_indexes = NULL;
+ GList *logout_session_indexes = NULL;
int rc = 0;
- if (LASSO_IS_SAMLP2_LOGOUT_REQUEST(profile->request) == FALSE)
- return LASSO_PROFILE_ERROR_MISSING_REQUEST;
+ goto_cleanup_if_fail_with_rc(LASSO_IS_SAMLP2_LOGOUT_REQUEST(profile->request),
+ LASSO_PROFILE_ERROR_MISSING_REQUEST);
logout_request = (LassoSamlp2LogoutRequest*)profile->request;
/* check the issuer */
lasso_assign_string(profile->remote_providerID,
logout_request->parent.Issuer->content);
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
- if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
- return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
- }
+ goto_cleanup_if_fail_with_rc(LASSO_IS_PROVIDER(remote_provider),
+ LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
/* create the response */
response = (LassoSamlp2StatusResponse*)lasso_samlp2_logout_response_new();
@@ -183,66 +170,46 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
if (name_id == NULL) {
lasso_saml20_profile_set_response_status_responder(
profile, LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
- return LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND);
}
if (profile->session == NULL) {
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
- return critical_error(LASSO_PROFILE_ERROR_SESSION_NOT_FOUND);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_SESSION_NOT_FOUND);
}
/* verify authentication */
- assertion_n = lasso_session_get_assertion(profile->session, profile->remote_providerID);
- if (LASSO_IS_SAML2_ASSERTION(assertion_n) == FALSE) {
+ if (profile->session) {
+ local_session_indexes = lasso_session_get_session_indexes(profile->session,
+ profile->remote_providerID, &name_id->parent);
+ }
+ if (! local_session_indexes) {
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
}
- assertion = LASSO_SAML2_ASSERTION(assertion_n);
-
- /* Verify name identifier and session matching */
- if (assertion->Subject == NULL) {
- lasso_saml20_profile_set_response_status(profile,
- LASSO_SAML2_STATUS_CODE_RESPONDER,
- "http://lasso.entrouvert.org/error/MalformedAssertion");
- return LASSO_PROFILE_ERROR_MISSING_SUBJECT;
- }
-
- if (lasso_saml2_name_id_equals(name_id, assertion->Subject->NameID) != TRUE) {
- lasso_saml20_profile_set_response_status_responder(profile,
- LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL);
- return LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
- }
/* verify session index */
- if (assertion->AuthnStatement) {
- if (! LASSO_IS_SAML2_AUTHN_STATEMENT(assertion->AuthnStatement->data)) {
+ if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP && logout_request->SessionIndex == NULL) {
+ /* ok, no SessionIndex from IdP, all sessions logout */
+ } else {
+ GList *i, *j;
+ int ok = 0;
- lasso_saml20_profile_set_response_status(profile,
- LASSO_SAML2_STATUS_CODE_RESPONDER, "http://lasso.entrouvert.org/error/MalformedAssertion");
- return LASSO_PROFILE_ERROR_BAD_SESSION_DUMP;
- }
- if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP && logout_request->SessionIndex == NULL) {
- /* ok, no SessionIndex from IdP, all sessions logout */
- } else {
- GList *session_indexes = lasso_samlp2_logout_request_get_session_indexes(logout_request);
- int ok = 0;
- char *assertion_SessionIndex = NULL;
- GList *iter;
-
- assertion_SessionIndex = _lasso_saml2_assertion_get_session_index(assertion);
- lasso_foreach(iter, session_indexes) {
- if (lasso_strisequal((char*)iter->data, assertion_SessionIndex)) {
+ logout_session_indexes = lasso_samlp2_logout_request_get_session_indexes(logout_request);
+
+ lasso_foreach(i, logout_session_indexes) {
+ lasso_foreach(j, local_session_indexes) {
+ if (lasso_strisequal((char*)i->data, (char*)j->data)) {
ok = 1;
}
}
- lasso_release_list_of_strings(session_indexes);
- if (! ok) {
- lasso_saml20_profile_set_response_status_responder(profile,
- LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
- return LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
- }
+ }
+ if (! ok) {
+ lasso_saml20_profile_set_response_status_responder(profile,
+ LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+ goto_cleanup_with_rc(LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL);
}
}
@@ -259,7 +226,7 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
if (logout->private_data->all_soap == FALSE) {
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_LIB_STATUS_CODE_UNSUPPORTED_PROFILE);
- return LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE;
+ goto_cleanup_with_rc(LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE);
}
}
@@ -279,6 +246,8 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
cleanup:
lasso_release_gobject(response);
+ lasso_release_list_of_strings(local_session_indexes);
+ lasso_release_list_of_strings(logout_session_indexes);
return rc;
}
@@ -286,22 +255,15 @@ static void
check_soap_support(G_GNUC_UNUSED gchar *key, LassoProvider *provider, LassoProfile *profile)
{
const GList *supported_profiles;
- LassoSaml2Assertion *assertion;
- LassoNode *assertion_n;
if (strcmp(provider->ProviderID, profile->remote_providerID) == 0)
return; /* original service provider (initiated logout) */
- assertion_n = lasso_session_get_assertion(profile->session, provider->ProviderID);
- if (LASSO_IS_SAML2_ASSERTION(assertion_n) == FALSE) {
- return; /* not authenticated with this provider */
+ if (! lasso_session_has_slo_session(profile->session, provider->ProviderID)) {
+ return;
}
-
- assertion = LASSO_SAML2_ASSERTION(assertion_n);
-
supported_profiles = lasso_provider_get_metadata_list(provider,
"SingleLogoutService SOAP");
-
if (supported_profiles)
return; /* provider support profile */