diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c index 7567a47d..51f82f4c 100644 --- a/lasso/id-ff/logout.c +++ b/lasso/id-ff/logout.c @@ -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; } /** diff --git a/lasso/xml/lib_logout_request.c b/lasso/xml/lib_logout_request.c index 13124c2e..143ec83e 100644 --- a/lasso/xml/lib_logout_request.c +++ b/lasso/xml/lib_logout_request.c @@ -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; +} diff --git a/lasso/xml/lib_logout_request.h b/lasso/xml/lib_logout_request.h index b61b3bfc..75732309 100644 --- a/lasso/xml/lib_logout_request.h +++ b/lasso/xml/lib_logout_request.h @@ -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 */