[id-ff 1.1] add support for multiple SessionIndex to lib:LogoutRequest
Combined with the new LassoSession storage for SessionIndex, it should fix many bugs when doing SLO.
This commit is contained in:
parent
ee4058bc22
commit
b016558d06
|
@ -518,14 +518,13 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
|
|||
LassoProfile *profile;
|
||||
LassoProvider *remote_provider;
|
||||
LassoSamlNameIdentifier *nameIdentifier = NULL;
|
||||
LassoSaml2EncryptedElement *encryptedNameIdentifier = NULL;
|
||||
LassoNode *assertion_n, *name_identifier_n;
|
||||
LassoSamlAssertion *assertion;
|
||||
LassoSamlSubjectStatementAbstract *subject_statement = NULL;
|
||||
LassoFederation *federation = NULL;
|
||||
gboolean is_http_redirect_get_method = FALSE;
|
||||
LassoSession *session;
|
||||
char *session_index = NULL;
|
||||
GList *name_ids = NULL;
|
||||
GList *session_indexes = NULL;
|
||||
LassoLibLogoutRequest *lib_logout_request = NULL;
|
||||
LassoSamlpRequestAbstract *request_abstract = NULL;
|
||||
int rc = 0;
|
||||
|
||||
g_return_val_if_fail(LASSO_IS_LOGOUT(logout), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
||||
|
||||
|
@ -546,75 +545,27 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
|
|||
lasso_assign_string(profile->remote_providerID, remote_providerID);
|
||||
}
|
||||
if (profile->remote_providerID == NULL) {
|
||||
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
||||
goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
||||
}
|
||||
|
||||
/* get the provider */
|
||||
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_with_rc(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
||||
}
|
||||
|
||||
IF_SAML2(profile) {
|
||||
return lasso_saml20_logout_init_request(logout, remote_provider, http_method);
|
||||
}
|
||||
|
||||
/* get assertion */
|
||||
assertion_n = lasso_session_get_assertion(session, profile->remote_providerID);
|
||||
if (LASSO_IS_SAML_ASSERTION(assertion_n) == FALSE) {
|
||||
return critical_error(LASSO_PROFILE_ERROR_MISSING_ASSERTION);
|
||||
}
|
||||
|
||||
assertion = LASSO_SAML_ASSERTION(assertion_n);
|
||||
|
||||
if (assertion->AuthenticationStatement && LASSO_IS_LIB_AUTHENTICATION_STATEMENT(
|
||||
assertion->AuthenticationStatement)) {
|
||||
LassoLibAuthenticationStatement *as =
|
||||
LASSO_LIB_AUTHENTICATION_STATEMENT(assertion->AuthenticationStatement);
|
||||
if (as->SessionIndex)
|
||||
lasso_assign_string(session_index, as->SessionIndex);
|
||||
}
|
||||
|
||||
/* if format is one time, then get name identifier from assertion,
|
||||
else get name identifier from federation */
|
||||
if (LASSO_IS_SAML_SUBJECT_STATEMENT_ABSTRACT(assertion->AuthenticationStatement)) {
|
||||
subject_statement = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(
|
||||
assertion->AuthenticationStatement);
|
||||
if (subject_statement && subject_statement->Subject) {
|
||||
nameIdentifier = subject_statement->Subject->NameIdentifier;
|
||||
encryptedNameIdentifier =
|
||||
subject_statement->Subject->EncryptedNameIdentifier;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Should first decrypt the EncryptedNameIdentifier */
|
||||
|
||||
if ((nameIdentifier && strcmp(nameIdentifier->Format,
|
||||
LASSO_LIB_NAME_IDENTIFIER_FORMAT_ONE_TIME) != 0)
|
||||
|| encryptedNameIdentifier) {
|
||||
|
||||
if (LASSO_IS_IDENTITY(profile->identity) == FALSE) {
|
||||
return critical_error(LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND);
|
||||
}
|
||||
federation = g_hash_table_lookup(profile->identity->federations,
|
||||
profile->remote_providerID);
|
||||
if (federation == NULL) {
|
||||
return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
|
||||
}
|
||||
|
||||
name_identifier_n = lasso_profile_get_nameIdentifier(profile);
|
||||
if (name_identifier_n == NULL) {
|
||||
return critical_error(LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND);
|
||||
}
|
||||
nameIdentifier = LASSO_SAML_NAME_IDENTIFIER(name_identifier_n);
|
||||
if (federation->local_nameIdentifier) {
|
||||
lasso_assign_gobject(profile->nameIdentifier, federation->local_nameIdentifier);
|
||||
} else {
|
||||
lasso_assign_gobject(profile->nameIdentifier, nameIdentifier);
|
||||
}
|
||||
} else {
|
||||
lasso_assign_gobject(profile->nameIdentifier, nameIdentifier);
|
||||
name_ids = lasso_session_get_name_ids(session, profile->remote_providerID);
|
||||
if (! name_ids) {
|
||||
goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER);
|
||||
}
|
||||
nameIdentifier = name_ids->data;
|
||||
lasso_assign_gobject(profile->nameIdentifier, nameIdentifier);
|
||||
session_indexes = lasso_session_get_session_indexes(session,
|
||||
profile->remote_providerID, profile->nameIdentifier);
|
||||
|
||||
/* get / verify http method */
|
||||
if (http_method == LASSO_HTTP_METHOD_ANY) {
|
||||
|
@ -634,7 +585,7 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
|
|||
* failed, since the remote provider doesn't
|
||||
* support any logout. remove assertion
|
||||
* unconditionnaly. */
|
||||
lasso_session_remove_assertion(profile->session,
|
||||
lasso_session_remove_assertion(session,
|
||||
profile->remote_providerID);
|
||||
if (logout->initial_remote_providerID && logout->initial_request) {
|
||||
lasso_assign_string(profile->remote_providerID,
|
||||
|
@ -647,48 +598,49 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
|
|||
0));
|
||||
}
|
||||
}
|
||||
return LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE;
|
||||
goto_cleanup_with_rc(LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE);
|
||||
}
|
||||
}
|
||||
|
||||
/* build a new request object from http method */
|
||||
if (http_method == LASSO_HTTP_METHOD_SOAP) {
|
||||
lasso_assign_new_gobject(profile->request, lasso_lib_logout_request_new_full(
|
||||
lib_logout_request = (LassoLibLogoutRequest*)lasso_lib_logout_request_new_full(
|
||||
LASSO_PROVIDER(profile->server)->ProviderID,
|
||||
nameIdentifier,
|
||||
profile->server->certificate ?
|
||||
LASSO_SIGNATURE_TYPE_WITHX509 : LASSO_SIGNATURE_TYPE_SIMPLE,
|
||||
LASSO_SIGNATURE_METHOD_RSA_SHA1));
|
||||
LASSO_SIGNATURE_METHOD_RSA_SHA1);
|
||||
} else { /* http_method == LASSO_HTTP_METHOD_REDIRECT */
|
||||
is_http_redirect_get_method = TRUE;
|
||||
lasso_assign_new_gobject(profile->request, lasso_lib_logout_request_new_full(
|
||||
lib_logout_request = (LassoLibLogoutRequest*)lasso_lib_logout_request_new_full(
|
||||
LASSO_PROVIDER(profile->server)->ProviderID,
|
||||
nameIdentifier,
|
||||
LASSO_SIGNATURE_TYPE_NONE,
|
||||
0));
|
||||
0);
|
||||
}
|
||||
|
||||
/* FIXME: Should encrypt nameIdentifier in the request here */
|
||||
request_abstract = &lib_logout_request->parent;
|
||||
|
||||
if (lasso_provider_get_protocol_conformance(remote_provider) < LASSO_PROTOCOL_LIBERTY_1_2) {
|
||||
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MajorVersion = 1;
|
||||
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MinorVersion = 1;
|
||||
request_abstract->MajorVersion = 1;
|
||||
request_abstract->MinorVersion = 1;
|
||||
}
|
||||
|
||||
lasso_assign_string(LASSO_LIB_LOGOUT_REQUEST(profile->request)->SessionIndex,
|
||||
session_index);
|
||||
lasso_assign_string(LASSO_LIB_LOGOUT_REQUEST(profile->request)->RelayState,
|
||||
profile->msg_relayState);
|
||||
lasso_lib_logout_request_set_session_indexes(lib_logout_request, session_indexes);
|
||||
lasso_assign_string(lib_logout_request->RelayState, profile->msg_relayState);
|
||||
|
||||
/* if logout request from a SP and if an HTTP Redirect/GET method, then remove assertion */
|
||||
if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP && is_http_redirect_get_method) {
|
||||
lasso_session_remove_assertion(profile->session, profile->remote_providerID);
|
||||
lasso_session_remove_assertion(session, profile->remote_providerID);
|
||||
}
|
||||
|
||||
/* Save the http method */
|
||||
logout->initial_http_request_method = http_method;
|
||||
|
||||
return 0;
|
||||
lasso_assign_gobject(profile->request, lib_logout_request);
|
||||
cleanup:
|
||||
lasso_release_gobject(lib_logout_request);
|
||||
lasso_release_list_of_strings(session_indexes);
|
||||
lasso_release_list_of_gobjects(name_ids);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,12 +60,22 @@
|
|||
/* private methods */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define LASSO_LIB_LOGOUT_REQUEST_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), LASSO_TYPE_LIB_LOGOUT_REQUEST, \
|
||||
struct _LassoLibLogoutRequestPrivate))
|
||||
|
||||
struct _LassoLibLogoutRequestPrivate {
|
||||
GList *SessionIndex;
|
||||
};
|
||||
|
||||
static struct XmlSnippet schema_snippets[] = {
|
||||
{ "Extension", SNIPPET_EXTENSION, G_STRUCT_OFFSET(LassoLibLogoutRequest, Extension), NULL, NULL, NULL},
|
||||
{ "ProviderID", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibLogoutRequest, ProviderID), NULL, NULL, NULL},
|
||||
{ "NameIdentifier", SNIPPET_NODE, G_STRUCT_OFFSET(LassoLibLogoutRequest, NameIdentifier),
|
||||
NULL, LASSO_SAML_ASSERTION_PREFIX, LASSO_SAML_ASSERTION_HREF},
|
||||
{ "SessionIndex", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibLogoutRequest, SessionIndex), NULL, NULL, NULL},
|
||||
{ "SessionIndex", SNIPPET_LIST_CONTENT|SNIPPET_PRIVATE, G_STRUCT_OFFSET(struct
|
||||
_LassoLibLogoutRequestPrivate, SessionIndex), NULL, NULL, NULL},
|
||||
{ "RelayState", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibLogoutRequest, RelayState), NULL, NULL, NULL},
|
||||
{ "consent", SNIPPET_ATTRIBUTE, G_STRUCT_OFFSET(LassoLibLogoutRequest, consent), NULL, NULL, NULL},
|
||||
{ "NotOnOrAfter", SNIPPET_ATTRIBUTE,
|
||||
|
@ -136,6 +146,7 @@ class_init(LassoLibLogoutRequestClass *klass)
|
|||
lasso_node_class_set_ns(nclass, LASSO_LIB_HREF, LASSO_LIB_PREFIX);
|
||||
lasso_node_class_add_snippets(nclass, schema_snippets);
|
||||
lasso_node_class_add_query_snippets(nclass, query_snippets);
|
||||
g_type_class_add_private(nclass, sizeof(struct _LassoLibLogoutRequestPrivate));
|
||||
}
|
||||
|
||||
GType
|
||||
|
@ -208,3 +219,56 @@ lasso_lib_logout_request_new_full(char *providerID, LassoSamlNameIdentifier *nam
|
|||
|
||||
return LASSO_NODE(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* lasso_lib_logout_request_set_session_indexes:
|
||||
* @lib_logout_request: a #LassoLibLogoutRequest object
|
||||
* @session_indexes:(element-type string): a list of session indexes
|
||||
*
|
||||
* Set the SessionIndex node for this idff:LogoutRequest.
|
||||
*/
|
||||
void
|
||||
lasso_lib_logout_request_set_session_indexes(LassoLibLogoutRequest *lib_logout_request,
|
||||
GList *session_indexes)
|
||||
{
|
||||
char *first = NULL;
|
||||
struct _LassoLibLogoutRequestPrivate *private_data;
|
||||
|
||||
if (! LASSO_IS_LIB_LOGOUT_REQUEST(lib_logout_request))
|
||||
return;
|
||||
private_data = LASSO_LIB_LOGOUT_REQUEST_GET_PRIVATE(lib_logout_request);
|
||||
if (session_indexes) {
|
||||
first = session_indexes->data;
|
||||
session_indexes = g_list_next(session_indexes);
|
||||
}
|
||||
lasso_assign_string(lib_logout_request->SessionIndex, first);
|
||||
lasso_assign_list_of_strings(private_data->SessionIndex, session_indexes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* lasso_lib_logout_request_get_session_indexes:
|
||||
* @lib_logout_request: a #LassoLibLogoutRequest object
|
||||
*
|
||||
* Get the SessionIndex node for this idff:LogoutRequest.
|
||||
*
|
||||
* Return value:(transfer full)(element-type utf8): a list of strings
|
||||
*/
|
||||
GList*
|
||||
lasso_lib_logout_request_get_session_indexes(LassoLibLogoutRequest *lib_logout_request)
|
||||
{
|
||||
struct _LassoLibLogoutRequestPrivate *private_data;
|
||||
GList *ret = NULL;
|
||||
GList *i = NULL;
|
||||
|
||||
if (! LASSO_IS_LIB_LOGOUT_REQUEST(lib_logout_request))
|
||||
return NULL;
|
||||
private_data = LASSO_LIB_LOGOUT_REQUEST_GET_PRIVATE(lib_logout_request);
|
||||
if (lib_logout_request->SessionIndex) {
|
||||
lasso_list_add_string(ret, lib_logout_request->SessionIndex);
|
||||
}
|
||||
lasso_foreach(i, private_data->SessionIndex) {
|
||||
lasso_list_add_string(ret, i->data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,13 @@ LASSO_EXPORT LassoNode* lasso_lib_logout_request_new_full(
|
|||
char *providerID, LassoSamlNameIdentifier *nameIdentifier,
|
||||
LassoSignatureType sign_type, LassoSignatureMethod sign_method);
|
||||
|
||||
LASSO_EXPORT void lasso_lib_logout_request_set_session_indexes(
|
||||
LassoLibLogoutRequest *lib_logout_request,
|
||||
GList *session_indexes);
|
||||
|
||||
LASSO_EXPORT GList* lasso_lib_logout_request_get_session_indexes(
|
||||
LassoLibLogoutRequest *lib_logout_request);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
Loading…
Reference in New Issue