summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-12-23 11:21:36 +0100
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-12-23 11:21:36 +0100
commit8f06751564ed5f767345e17ae0f09ee8199e4a49 (patch)
treeeba37902b77b7169bbb79394daad95a550d56742
parent69c61627d3b8494c9f8544f19293c9b345ec103d (diff)
parentaf4c8de94722d51dd000276eb5e51c26c314f903 (diff)
Merge branch 'more-datas-in-sessions'
-rw-r--r--docs/reference/lasso/lasso-docs.sgml2
-rw-r--r--docs/reference/lasso/lasso-sections.txt1
-rw-r--r--lasso/debug.h1
-rw-r--r--lasso/id-ff/login.c86
-rw-r--r--lasso/id-ff/logout.c112
-rw-r--r--lasso/id-ff/profile.c2
-rw-r--r--lasso/id-ff/profile.h3
-rw-r--r--lasso/id-ff/session.c420
-rw-r--r--lasso/id-ff/session.h7
-rw-r--r--lasso/id-ff/sessionprivate.h6
-rw-r--r--lasso/lasso.c5
-rw-r--r--lasso/saml-2.0/login.c58
-rw-r--r--lasso/saml-2.0/logout.c146
-rw-r--r--lasso/xml/lib_logout_request.c64
-rw-r--r--lasso/xml/lib_logout_request.h7
-rw-r--r--lasso/xml/saml_name_identifier.c14
-rw-r--r--lasso/xml/saml_name_identifier.h3
-rw-r--r--lasso/xml/strings.h6
-rw-r--r--tests/login_tests.c28
19 files changed, 708 insertions, 263 deletions
diff --git a/docs/reference/lasso/lasso-docs.sgml b/docs/reference/lasso/lasso-docs.sgml
index e92d447e..b71fefcf 100644
--- a/docs/reference/lasso/lasso-docs.sgml
+++ b/docs/reference/lasso/lasso-docs.sgml
@@ -213,7 +213,7 @@ the <ulink url="http://lasso.entrouvert.org/license">GNU General Public License<
<chapter id="saml2">
<title>SAML 2.0 Single Sign On profiles</title>
<para>
- The profile <link linkend="lasso-LassoLogin">LassoLogin</link> and <link linkend="lasso-LassoLogout">LassoLogout</link> are shared between SAML
+ The profile <link linkend="lasso-login">LassoLogin</link> and <link linkend="lasso-LassoLogout">LassoLogout</link> are shared between SAML
2.0 and ID-FF 1.2, depending on the declared protocol support,
Lasso will create request respecting the chosen standard. Beware
that initialization of the <link linkend="lasso-LassoLogin">LassoLogin</link> object, after construction,
diff --git a/docs/reference/lasso/lasso-sections.txt b/docs/reference/lasso/lasso-sections.txt
index 74d998a5..cdd019fa 100644
--- a/docs/reference/lasso/lasso-sections.txt
+++ b/docs/reference/lasso/lasso-sections.txt
@@ -220,7 +220,6 @@ LASSO_LECP_GET_CLASS
<SECTION>
<FILE>login</FILE>
-LassoLoginProtocolProfile
<TITLE>LassoLogin</TITLE>
LassoLogin
lasso_login_new
diff --git a/lasso/debug.h b/lasso/debug.h
index ce294ac7..f98f7882 100644
--- a/lasso/debug.h
+++ b/lasso/debug.h
@@ -37,6 +37,7 @@ LASSO_EXPORT extern gboolean lasso_flag_memory_debug;
LASSO_EXPORT extern gboolean lasso_flag_strict_checking;
LASSO_EXPORT extern gboolean lasso_flag_add_signature;
LASSO_EXPORT extern gboolean lasso_flag_sign_messages;
+LASSO_EXPORT extern gboolean lasso_flag_thin_sessions;
#ifdef __cplusplus
}
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index dd3cc5c7..9191e033 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -259,6 +259,7 @@
#include "../xml/saml_conditions.h"
#include "../xml/samlp_response.h"
#include "../xml/saml-2.0/saml2_encrypted_element.h"
+#include "../xml/misc_text_node.h"
#include "profileprivate.h"
@@ -401,19 +402,20 @@ lasso_login_build_assertion(LassoLogin *login,
}
}
+ /* add session index */
+ if (lasso_provider_get_first_http_method(&login->parent.server->parent,
+ provider, LASSO_MD_PROTOCOL_TYPE_SINGLE_LOGOUT) != LASSO_HTTP_METHOD_NONE) {
+ lasso_assign_string(as->SessionIndex, assertion->AssertionID);
+ }
+
assertion->AuthenticationStatement = LASSO_SAML_AUTHENTICATION_STATEMENT(as);
/* Save signing material in assertion private datas to be able to sign later */
lasso_check_good_rc(lasso_server_set_signature_for_provider_by_name(login->parent.server,
profile->remote_providerID, (LassoNode*)assertion));
-
- if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST || \
- login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP) {
- /* only add assertion if response is an AuthnResponse */
- lasso_list_add_gobject(LASSO_SAMLP_RESPONSE(profile->response)->Assertion,
- assertion);
- }
+ lasso_list_add_gobject(LASSO_SAMLP_RESPONSE(profile->response)->Assertion,
+ assertion);
#ifdef LASSO_WSF_ENABLED
lasso_login_assertion_add_discovery(login, assertion);
@@ -858,6 +860,8 @@ lasso_login_build_assertion_artifact(LassoLogin *login)
b64_samlArt = xmlSecBase64Encode(samlArt, 42, 0);
lasso_assign_string(login->assertionArtifact, (char*)b64_samlArt);
+ lasso_assign_string(login->parent.private_data->artifact,
+ (char*)b64_samlArt);
lasso_release_xml_string(b64_samlArt);
}
@@ -906,12 +910,12 @@ lasso_login_build_assertion_artifact(LassoLogin *login)
gint
lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
{
- LassoProvider *remote_provider;
- LassoProfile *profile;
- gchar *url;
- xmlChar *b64_samlArt;
- char *relayState;
- gint ret = 0;
+ LassoProvider *remote_provider = NULL;
+ LassoProfile *profile = NULL;
+ gchar *url = NULL;
+ xmlChar *b64_samlArt = NULL;
+ xmlChar *relayState = NULL;
+ gint rc = 0;
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
@@ -920,7 +924,7 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
if (profile->remote_providerID == NULL) {
/* this means lasso_login_init_request was not called before */
- return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
}
IF_SAML2(profile) {
@@ -928,18 +932,18 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
if (http_method != LASSO_HTTP_METHOD_REDIRECT && http_method != LASSO_HTTP_METHOD_POST) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
}
/* ProtocolProfile must be BrwsArt */
if (login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
}
/* build artifact infos */
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);
url = lasso_provider_get_assertion_consumer_service_url(remote_provider,
LASSO_LIB_AUTHN_REQUEST(profile->request)->AssertionConsumerServiceID);
@@ -985,12 +989,12 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
b64_samlArt = xmlStrdup((xmlChar*)login->assertionArtifact);
- relayState = (char*)xmlURIEscapeStr(
+ relayState = xmlURIEscapeStr(
(xmlChar*)LASSO_LIB_AUTHN_REQUEST(profile->request)->RelayState, NULL);
if (http_method == LASSO_HTTP_METHOD_REDIRECT) {
xmlChar *escaped_artifact = xmlURIEscapeStr(b64_samlArt, NULL);
- gchar *query;
+ gchar *query = NULL;
if (relayState == NULL) {
query = g_strdup_printf("SAMLart=%s", escaped_artifact);
@@ -1000,20 +1004,16 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
lasso_release_string(query);
-
- xmlFree(escaped_artifact);
+ lasso_release_xml_string(escaped_artifact);
}
if (http_method == LASSO_HTTP_METHOD_POST) {
lasso_assign_string(profile->msg_url, url);
lasso_assign_string(profile->msg_body, (char*)b64_samlArt);
if (relayState != NULL) {
- lasso_assign_string(profile->msg_relayState, relayState);
+ lasso_assign_string(profile->msg_relayState, (char*)relayState);
}
}
- lasso_release_string(url);
- xmlFree(b64_samlArt);
- xmlFree(relayState);
if (strcmp(LASSO_SAMLP_RESPONSE(profile->response)->Status->StatusCode->Value,
LASSO_SAML_STATUS_CODE_SUCCESS) != 0) {
@@ -1026,7 +1026,25 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
lasso_session_remove_status(profile->session, profile->remote_providerID);
}
- return ret;
+ /* store the response as the artifact message */
+ lasso_check_good_rc(lasso_server_set_signature_for_provider_by_name(
+ profile->server,
+ profile->remote_providerID,
+ profile->response));
+ /* comply with the new way of storing artifacts */
+ lasso_assign_string(profile->private_data->artifact,
+ login->assertionArtifact);
+ /* Artifact profile for ID-FF 1.2 is special, this is not the full message which is relayed
+ * but only its assertion content, the Response container is changed from a
+ * lib:AuthnResponse to a samlp:Response.
+ */
+ lasso_assign_new_string(profile->private_data->artifact_message,
+ lasso_node_export_to_xml((LassoNode*)login->assertion));
+cleanup:
+ lasso_release_string(url);
+ lasso_release_xml_string(b64_samlArt);
+ lasso_release_xml_string(relayState);
+ return rc;
}
/**
@@ -1363,8 +1381,8 @@ cleanup:
gint
lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
{
- LassoProvider *remote_provider;
- LassoProfile *profile;
+ LassoProvider *remote_provider = NULL;
+ LassoProfile *profile = NULL;
lasso_error_t rc = 0;
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
@@ -1426,6 +1444,16 @@ lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
lasso_profile_set_response_status(profile,
LASSO_SAML_STATUS_CODE_SUCCESS);
lasso_session_remove_status(profile->session, remote_providerID);
+ } else if (profile->private_data->artifact_message) {
+ xmlDoc *doc;
+ char *artifact_message = profile->private_data->artifact_message;
+ doc = lasso_xml_parse_memory(artifact_message,
+ strlen(artifact_message));
+ lasso_profile_set_response_status(profile,
+ LASSO_SAML_STATUS_CODE_SUCCESS);
+ lasso_list_add_new_gobject(((LassoSamlpResponse*)profile->response)->Assertion,
+ lasso_misc_text_node_new_with_xml_node(xmlDocGetRootElement(doc)));
+ lasso_release_doc(doc);
}
}
} else {
@@ -2174,6 +2202,8 @@ lasso_login_process_request_msg(LassoLogin *login, gchar *request_msg)
/* get AssertionArtifact */
lasso_assign_string(login->assertionArtifact,
LASSO_SAMLP_REQUEST(profile->request)->AssertionArtifact);
+ lasso_assign_string(login->parent.private_data->artifact,
+ login->assertionArtifact);
/* Keep a copy of request msg so signature can be verified when we get
* the providerId in lasso_login_build_response_msg()
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/id-ff/profile.c b/lasso/id-ff/profile.c
index bc9a65d1..768c3ea2 100644
--- a/lasso/id-ff/profile.c
+++ b/lasso/id-ff/profile.c
@@ -675,7 +675,7 @@ lasso_profile_set_soap_fault_response(LassoProfile *profile, const char *faultco
*
* Return value: #LASSO_PROVIDER_ROLE_NONE if nothing can be said, #LASSO_PROVIDER_ROLE_SP if a
* federation qualifier by @remote_provider_id exists or #LASSO_PROVIDER_ROLE_IDP if a federation
- * qualifier by our own #LassoProvider.providerID exists.
+ * qualifier by our own #LassoProvider.ProviderID exists.
*/
LassoProviderRole lasso_profile_sso_role_with(LassoProfile *profile, const char *remote_provider_id)
{
diff --git a/lasso/id-ff/profile.h b/lasso/id-ff/profile.h
index d04f1727..096d2f92 100644
--- a/lasso/id-ff/profile.h
+++ b/lasso/id-ff/profile.h
@@ -139,6 +139,9 @@ typedef enum {
* HTTP-Post binding), the body of the POST will be in this field,
* @msg_relayState: put there the relaystate to put in the genereated URL for HTTP-Redirect or
* HTTP-Get binding.
+ * @signature_status: result of the last signature validation.
+ * @identity: the state of federation linking for the current user.
+ * @session: the state of global SSO session for the current user.
*
* #LassoProfile, child class of #LassoNode is the basis object of profiles object like #LassoLogin, #LassoLogout,
* #LassoDefederation, #LassoNameIdentifierMapping, #LassoNameRegistration, #LassoNameIdManagement
diff --git a/lasso/id-ff/session.c b/lasso/id-ff/session.c
index d55e35b5..d5294ff3 100644
--- a/lasso/id-ff/session.c
+++ b/lasso/id-ff/session.c
@@ -32,9 +32,12 @@
#include "../lasso_config.h"
#include "session.h"
#include "sessionprivate.h"
+#include "../xml/lib_authentication_statement.h"
#include "../xml/saml_assertion.h"
+#include "../xml/saml-2.0/saml2_authn_statement.h"
#include "../xml/saml-2.0/saml2_assertion.h"
#include "../utils.h"
+#include "../debug.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -45,10 +48,145 @@
#include "../id-wsf-2.0/sessionprivate.h"
#endif
+static gboolean lasso_match_name_id(LassoNode *a, LassoNode *b);
+
+struct _NidAndSessionIndex {
+ LassoNode *name_id;
+ char *assertion_id;
+ char *session_index;
+};
+
+struct _NidAndSessionIndex *
+lasso_new_nid_and_session_index(LassoNode *name_id, const char *assertion_id, const char
+ *session_index)
+{
+ struct _NidAndSessionIndex *nid_and_session_index = g_new0(struct _NidAndSessionIndex, 1);
+ lasso_assign_gobject(nid_and_session_index->name_id, name_id);
+ lasso_assign_string(nid_and_session_index->assertion_id, assertion_id);
+ lasso_assign_string(nid_and_session_index->session_index, session_index);
+
+ return nid_and_session_index;
+}
+
+void
+lasso_release_nid_and_session_index(struct _NidAndSessionIndex *nid_and_session_index)
+{
+ lasso_release_gobject(nid_and_session_index->name_id);
+ lasso_release_string(nid_and_session_index->session_index);
+ lasso_release_string(nid_and_session_index->assertion_id);
+}
+
+void
+lasso_release_list_of_nid_an_session_index(GList *list)
+{
+ g_list_foreach(list, (GFunc)lasso_release_nid_and_session_index, NULL);
+ g_list_free(list);
+}
+
/*****************************************************************************/
/* public methods */
/*****************************************************************************/
+static void
+lasso_session_add_nid_and_session_index(LassoSession *session,
+ const char *providerID,
+ struct _NidAndSessionIndex *nid_and_session_index)
+{
+ GList *l = g_hash_table_lookup(session->private_data->nid_and_session_indexes, providerID);
+ GList *i;
+
+ lasso_foreach(i, l) {
+ struct _NidAndSessionIndex *other_nid_and_sid = i->data;
+
+ /* do some sharing and limit doublons */
+ if (lasso_match_name_id(other_nid_and_sid->name_id, nid_and_session_index->name_id)) {
+ if (lasso_strisequal(other_nid_and_sid->session_index, nid_and_session_index->session_index)) {
+ lasso_release_nid_and_session_index(nid_and_session_index);
+ return;
+ }
+ // lasso_assign_gobject(nid_and_session_index->name_id, other_nid_and_sid->name_id);
+ }
+ }
+ if (l) {
+ l = g_list_append(l, nid_and_session_index);
+ } else {
+ l = g_list_append(l, nid_and_session_index);
+ g_hash_table_insert(session->private_data->nid_and_session_indexes,
+ g_strdup(providerID), l);
+ }
+}
+
+/**
+ * lasso_session_add_assertion_nid_and_session_index:
+ *
+ * Extract NameID and SessionIndex and keep them around.
+ *
+ */
+static gint
+lasso_session_add_assertion_nid_and_session_index(LassoSession *session, const gchar *providerID,
+ LassoNode *assertion)
+{
+ struct _NidAndSessionIndex *nid_and_session_index = NULL;
+
+ lasso_bad_param(SESSION, session);
+ lasso_null_param(assertion);
+
+ if (LASSO_IS_SAML_ASSERTION(assertion)) { /* saml 1.1 */
+ LassoSamlAssertion *saml_assertion = (LassoSamlAssertion*) assertion;
+ LassoLibAuthenticationStatement *auth_statement = NULL;
+ LassoSamlSubjectStatementAbstract *ss = NULL;
+
+ if (saml_assertion->SubjectStatement)
+ ss = &saml_assertion->SubjectStatement->parent;
+ else if (saml_assertion->AuthenticationStatement)
+ ss = &saml_assertion->AuthenticationStatement->parent;
+ else
+ return LASSO_PARAM_ERROR_INVALID_VALUE;
+ if (! ss->Subject)
+ return LASSO_PARAM_ERROR_INVALID_VALUE;
+ if (! ss->Subject->NameIdentifier)
+ return LASSO_PARAM_ERROR_INVALID_VALUE;
+ if (! LASSO_IS_LIB_AUTHENTICATION_STATEMENT(saml_assertion->AuthenticationStatement))
+ return LASSO_ERROR_UNIMPLEMENTED;
+ auth_statement = (LassoLibAuthenticationStatement*)
+ saml_assertion->AuthenticationStatement;
+ if (! auth_statement->SessionIndex)
+ return 0;
+ nid_and_session_index = lasso_new_nid_and_session_index(
+ (LassoNode*)ss->Subject->NameIdentifier,
+ saml_assertion->AssertionID,
+ auth_statement->SessionIndex);
+ lasso_session_add_nid_and_session_index(session,
+ providerID, nid_and_session_index);
+ } else if (LASSO_IS_SAML2_ASSERTION(assertion)) { /* saml 2.0 */
+ LassoSaml2Assertion *saml2_assertion = (LassoSaml2Assertion*) assertion;
+ GList *iter;
+
+ if (! saml2_assertion->Subject)
+ return LASSO_PARAM_ERROR_INVALID_VALUE;
+ if (! saml2_assertion->Subject->NameID)
+ return LASSO_PARAM_ERROR_INVALID_VALUE;
+ if (! saml2_assertion->AuthnStatement)
+ return 0;
+ lasso_foreach(iter, saml2_assertion->AuthnStatement) {
+ LassoSaml2AuthnStatement *authn_statement = iter->data;
+
+ if (authn_statement->SessionIndex) {
+ nid_and_session_index = lasso_new_nid_and_session_index(
+ (LassoNode*)saml2_assertion->Subject->NameID,
+ saml2_assertion->ID,
+ authn_statement->SessionIndex);
+ lasso_session_add_nid_and_session_index(session,
+ providerID,
+ nid_and_session_index);
+ }
+ }
+ } else {
+ return LASSO_ERROR_UNIMPLEMENTED;
+ }
+ return 0;
+}
+
static gint
lasso_session_add_assertion_simple(LassoSession *session, const char *providerID, LassoNode
*assertion)
@@ -57,12 +195,142 @@ lasso_session_add_assertion_simple(LassoSession *session, const char *providerID
g_return_val_if_fail(providerID != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
g_return_val_if_fail(assertion != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ if (lasso_flag_thin_sessions) { /* do not store the full assertion */
+ return 0;
+ }
g_hash_table_insert(session->assertions, g_strdup(providerID),
g_object_ref(assertion));
return 0;
}
+static gboolean
+lasso_match_name_id(LassoNode *a, LassoNode *b)
+{
+ if (LASSO_IS_SAML_NAME_IDENTIFIER(a) && LASSO_IS_SAML_NAME_IDENTIFIER(b)) {
+ return lasso_saml_name_identifier_equals((LassoSamlNameIdentifier*)a,
+ (LassoSamlNameIdentifier*)b);
+
+ } else if (LASSO_IS_SAML2_NAME_ID(a) && LASSO_IS_SAML2_NAME_ID(b)) {
+ return lasso_saml2_name_id_equals((LassoSaml2NameID*)a,
+ (LassoSaml2NameID*)b);
+ }
+ return FALSE;
+}
+
+/**
+ * lasso_session_get_session_indexes:
+ * @session: a #LassoSession object
+ * @providerID: a provider id
+ * @name_id: a #LassoSamlAssertion or #LassoSaml2Assertion object
+ *
+ * Gets all the registered session indexes for this session.
+ *
+ * Return value:(transfer full)(element-type utf8): a list of string containing the session index identifiers.
+ */
+GList*
+lasso_session_get_session_indexes(LassoSession *session,
+ const gchar *providerID,
+ LassoNode *node)
+{
+ GList *l = NULL, *iter = NULL;
+ GList *ret = NULL;
+
+ if (! LASSO_IS_SESSION(session))
+ return NULL;
+ if (! providerID)
+ return NULL;
+ l = g_hash_table_lookup(session->private_data->nid_and_session_indexes,
+ providerID);
+
+ lasso_foreach(iter, l) {
+ struct _NidAndSessionIndex *nid_and_session_index = iter->data;
+
+ if (! nid_and_session_index->session_index)
+ continue;
+
+ if (node && ! lasso_match_name_id(node, nid_and_session_index->name_id)) {
+ continue;
+ }
+ lasso_list_add_string(ret, nid_and_session_index->session_index);
+ }
+ return ret;
+}
+
+/**
+ * lasso_session_get_name_ids:
+ * @session: a #LassoSession object
+ * @providerID: a provider identifier
+ *
+ * List the known NameID coming from this provider during this session.
+ *
+ * Return value:(transfer full)(element-type LassoNode): a list of #LassoNode objects.
+ */
+GList*
+lasso_session_get_name_ids(LassoSession *session, const gchar *providerID)
+{
+ GList *nid_and_session_indexes = NULL;
+ GList *ret = NULL;
+ GList *i, *j;
+
+ if (! LASSO_IS_SESSION(session))
+ return NULL;
+
+ if (! providerID)
+ return NULL;
+
+ nid_and_session_indexes = g_hash_table_lookup(session->private_data->nid_and_session_indexes,
+ providerID);
+
+ lasso_foreach(i, nid_and_session_indexes) {
+ struct _NidAndSessionIndex *nid_and_session_index = i->data;
+ int ok = 1;
+
+ lasso_foreach(j, ret) {
+ if (lasso_match_name_id(j->data, nid_and_session_index->name_id)) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok) {
+ lasso_list_add_gobject(ret, nid_and_session_index->name_id);
+ }
+ }
+ return ret;
+}
+
+/**
+ * lasso_session_get_assertion_ids:
+ * @session: a #LassoSession object
+ * @providerID: a provider identifier
+ *
+ * List the ids of assertions received during the current session.
+ *
+ * Return value:(transfer full)(element-type utf8): a list of strings
+ */
+GList*
+lasso_session_get_assertion_ids(LassoSession *session, const gchar *providerID)
+{
+ GList *nid_and_session_indexes = NULL;
+ GList *ret = NULL;
+ GList *i;
+
+ if (! LASSO_IS_SESSION(session))
+ return NULL;
+
+ if (! providerID)
+ return NULL;
+
+ nid_and_session_indexes = g_hash_table_lookup(session->private_data->nid_and_session_indexes,
+ providerID);
+
+ lasso_foreach(i, nid_and_session_indexes) {
+ struct _NidAndSessionIndex *nid_and_session_index = i->data;
+ lasso_list_add_string(ret, nid_and_session_index->assertion_id);
+ }
+ return ret;
+}
+
/**
* lasso_session_add_assertion:
* @session: a #LassoSession
@@ -83,7 +351,10 @@ lasso_session_add_assertion(LassoSession *session, const char *providerID, Lasso
if (ret != 0) {
return ret;
}
-
+ ret = lasso_session_add_assertion_nid_and_session_index(session, providerID, assertion);
+ if (ret != 0) {
+ return ret;
+ }
/* ID-WSF specific need */
if (LASSO_IS_SAML_ASSERTION(assertion)) {
LassoSamlAssertion *saml_assertion = LASSO_SAML_ASSERTION(assertion);
@@ -253,7 +524,7 @@ lasso_session_get_status(LassoSession *session, const gchar *providerID)
}
static void
-add_providerID(gchar *key, G_GNUC_UNUSED LassoLibAssertion *assertion, LassoSession *session)
+add_providerID(gchar *key, G_GNUC_UNUSED struct _NidAndSessionIndex *ignored, LassoSession *session)
{
lasso_list_add_string(session->private_data->providerIDs, key);
}
@@ -277,7 +548,7 @@ lasso_session_get_provider_index(LassoSession *session, gint index)
g_return_val_if_fail(LASSO_IS_SESSION(session), NULL);
g_return_val_if_fail(session->private_data, NULL);
- length = g_hash_table_size(session->assertions);
+ length = g_hash_table_size(session->private_data->nid_and_session_indexes);
if (length == 0)
return NULL;
@@ -308,7 +579,8 @@ lasso_session_init_provider_ids(LassoSession *session)
g_return_if_fail(session->private_data);
lasso_release_list_of_strings(session->private_data->providerIDs);
- g_hash_table_foreach(session->assertions, (GHFunc)add_providerID, session);
+ g_hash_table_foreach(session->private_data->nid_and_session_indexes, (GHFunc)add_providerID,
+ session);
}
@@ -327,12 +599,18 @@ lasso_session_is_empty(LassoSession *session)
return TRUE;
}
- if (g_hash_table_size(session->assertions)) {
+ if (g_hash_table_size(session->assertions) +
+ g_hash_table_size(session->private_data->status) +
+ g_hash_table_size(session->private_data->assertions_by_id) +
+ g_hash_table_size(session->private_data->nid_and_session_indexes))
+ {
return FALSE;
}
- if (g_hash_table_size(session->private_data->status)) {
+#ifdef LASSO_WSF_ENABLED
+ if (g_hash_table_size(session->eprs)) {
return FALSE;
}
+#endif
return TRUE;
}
@@ -352,7 +630,10 @@ lasso_session_count_assertions(LassoSession *session)
if (! LASSO_IS_SESSION(session))
return -1;
- hashtable = session->assertions;
+ if (lasso_flag_thin_sessions)
+ hashtable = session->private_data->nid_and_session_indexes;
+ else
+ hashtable = session->assertions;
return hashtable ? g_hash_table_size(hashtable) : 0;
}
@@ -377,16 +658,21 @@ lasso_session_is_dirty(LassoSession *session)
gint
lasso_session_remove_assertion(LassoSession *session, const gchar *providerID)
{
- if (! LASSO_IS_SESSION(session) || lasso_strisempty(providerID)) {
- return LASSO_PARAM_ERROR_INVALID_VALUE;
- }
+ int rc = 0;
+ gboolean ok1, ok2;
+
+ lasso_bad_param(SESSION, session);
+ lasso_return_val_if_fail(! lasso_strisempty(providerID), LASSO_PARAM_ERROR_INVALID_VALUE);
- if (g_hash_table_remove(session->assertions, providerID)) {
+ ok1 = g_hash_table_remove(session->assertions, providerID);
+ ok2 = g_hash_table_remove(session->private_data->nid_and_session_indexes, providerID);
+
+ if (ok1 || ok2) {
session->is_dirty = TRUE;
- return 0;
+ } else {
+ rc = LASSO_PROFILE_ERROR_MISSING_ASSERTION;
}
-
- return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
+ return rc;
}
/**
@@ -490,6 +776,35 @@ add_status_childnode(gchar *key, LassoSamlpStatus *value, DumpContext *context)
xmlAddChild(t, lasso_node_get_xmlNode(LASSO_NODE(value), TRUE));
}
+#define NID_AND_SESSION_INDEX "NidAndSessionIndex"
+#define SESSION_INDEX "SessionIndex"
+#define PROVIDER_ID "ProviderID"
+#define ASSERTION_ID "AssertionID"
+
+static void
+xmlnode_add_assertion_nid_and_session_indexes(gchar *key, GList *nid_and_session_indexes, DumpContext *context)
+{
+ GList *iter;
+
+ if (! nid_and_session_indexes) {
+ return;
+ }
+ lasso_foreach(iter, nid_and_session_indexes) {
+ struct _NidAndSessionIndex *nid_and_session_index = iter->data;
+ xmlNode *node = xmlSecAddChild(context->parent, BAD_CAST NID_AND_SESSION_INDEX,
+ BAD_CAST LASSO_LASSO_HREF);
+
+ xmlSetProp(node, BAD_CAST PROVIDER_ID, BAD_CAST key);
+ xmlSetProp(node, BAD_CAST ASSERTION_ID, BAD_CAST nid_and_session_index->assertion_id);
+ if (nid_and_session_index->session_index) {
+ xmlSetProp(node, BAD_CAST SESSION_INDEX,
+ BAD_CAST nid_and_session_index->session_index);
+ }
+ xmlSecAddChildNode(node, lasso_node_get_xmlNode(nid_and_session_index->name_id,
+ FALSE));
+ }
+}
+
static xmlNode*
get_xmlNode(LassoNode *node, G_GNUC_UNUSED gboolean lasso_dump)
{
@@ -513,6 +828,10 @@ get_xmlNode(LassoNode *node, G_GNUC_UNUSED gboolean lasso_dump)
g_hash_table_foreach(session->private_data->assertions_by_id,
(GHFunc)add_assertion_by_id, &context);
}
+ if (g_hash_table_size(session->private_data->nid_and_session_indexes)) {
+ g_hash_table_foreach(session->private_data->nid_and_session_indexes,
+ (GHFunc)xmlnode_add_assertion_nid_and_session_indexes, &context);
+ }
#ifdef LASSO_WSF_ENABLED
lasso_session_id_wsf2_dump_eprs(session, xmlnode);
@@ -547,6 +866,39 @@ cleanup:
return ret;
}
+static void
+init_from_xml_nid_and_session_index(LassoNode *node, xmlNode *nid_and_session_index_node)
+{
+ xmlChar *session_index = NULL;
+ xmlChar *provider_id = NULL;
+ xmlChar *assertion_id = NULL;
+ xmlNode *nid;
+ LassoNode *name_id;
+ struct _NidAndSessionIndex *nid_and_session_index;
+
+ provider_id = xmlGetProp(nid_and_session_index_node, BAD_CAST PROVIDER_ID);
+ if (! provider_id)
+ goto cleanup;
+ assertion_id = xmlGetProp(nid_and_session_index_node, BAD_CAST ASSERTION_ID);
+ if (! assertion_id)
+ goto cleanup;
+ nid = xmlSecGetNextElementNode(nid_and_session_index_node->children);
+ if (! nid)
+ goto cleanup;
+ name_id = lasso_node_new_from_xmlNode(nid);
+ if (! node)
+ goto cleanup;
+ session_index = xmlGetProp(nid_and_session_index_node, BAD_CAST SESSION_INDEX);
+ nid_and_session_index = lasso_new_nid_and_session_index(name_id, (char*)assertion_id,
+ (char*)session_index);
+ lasso_session_add_nid_and_session_index((LassoSession*)node, (char*)provider_id,
+ nid_and_session_index);
+cleanup:
+ lasso_release_xml_string(session_index);
+ lasso_release_xml_string(provider_id);
+ lasso_release_xml_string(assertion_id);
+}
+
static int
init_from_xml(LassoNode *node, xmlNode *xmlnode)
{
@@ -573,6 +925,8 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
assertion = lasso_node_new_from_xmlNode(n);
lasso_session_add_assertion_simple(session, (char*)value, assertion);
+ /* automatic upgrade from old session serialization to the new */
+ lasso_session_add_assertion_nid_and_session_index(session, (char*)value, assertion);
lasso_release_gobject(assertion);
xmlFree(value);
}
@@ -605,6 +959,10 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
status);
}
}
+ if (xmlSecCheckNodeName(t, BAD_CAST NID_AND_SESSION_INDEX,
+ BAD_CAST LASSO_LASSO_HREF)) {
+ init_from_xml_nid_and_session_index(node, t);
+ }
#ifdef LASSO_WSF_ENABLED
lasso_session_id_wsf2_init_eprs(session, t);
@@ -635,6 +993,7 @@ dispose(GObject *object)
lasso_release_ghashtable(session->private_data->status);
lasso_release_list_of_strings(session->private_data->providerIDs);
lasso_release_ghashtable(session->private_data->assertions_by_id);
+ lasso_release_ghashtable(session->private_data->nid_and_session_indexes);
#ifdef LASSO_WSF_ENABLED
lasso_release_ghashtable(session->private_data->eprs);
@@ -643,17 +1002,6 @@ dispose(GObject *object)
G_OBJECT_CLASS(parent_class)->dispose(object);
}
-static void
-finalize(GObject *object)
-{
- LassoSession *session = LASSO_SESSION(object);
-
- lasso_release(session->private_data);
- session->private_data = NULL;
-
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -661,7 +1009,7 @@ finalize(GObject *object)
static void
instance_init(LassoSession *session)
{
- session->private_data = g_new0 (LassoSessionPrivate, 1);
+ session->private_data = LASSO_SESSION_GET_PRIVATE(session);
session->private_data->dispose_has_run = FALSE;
session->private_data->providerIDs = NULL;
session->private_data->status = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -671,14 +1019,17 @@ instance_init(LassoSession *session)
g_hash_table_new_full(g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)xmlFree);
+ session->assertions = g_hash_table_new_full(g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free, (GDestroyNotify)lasso_node_destroy);
+ session->is_dirty = FALSE;
+ session->private_data->nid_and_session_indexes = g_hash_table_new_full(g_str_hash,
+ g_str_equal, (GDestroyNotify)g_free,
+ (GDestroyNotify)lasso_release_list_of_nid_an_session_index);
#ifdef LASSO_WSF_ENABLED
session->private_data->eprs = g_hash_table_new_full(g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_object_unref);
#endif
- session->assertions = g_hash_table_new_full(g_str_hash, g_str_equal,
- (GDestroyNotify)g_free, (GDestroyNotify)lasso_node_destroy);
- session->is_dirty = FALSE;
}
static void
@@ -692,9 +1043,9 @@ class_init(LassoSessionClass *klass)
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "Session");
lasso_node_class_set_ns(nclass, LASSO_LASSO_HREF, LASSO_LASSO_PREFIX);
+ g_type_class_add_private(nclass, sizeof(LassoSessionPrivate));
G_OBJECT_CLASS(klass)->dispose = dispose;
- G_OBJECT_CLASS(klass)->finalize = finalize;
}
GType
@@ -784,3 +1135,12 @@ void lasso_session_destroy(LassoSession *session)
return;
lasso_node_destroy(LASSO_NODE(session));
}
+
+gboolean
+lasso_session_has_slo_session(LassoSession *session, const gchar *provider_id)
+{
+ if (! LASSO_IS_SESSION(session))
+ return FALSE;
+ return g_hash_table_lookup(session->private_data->nid_and_session_indexes, provider_id) !=
+ NULL;
+}
diff --git a/lasso/id-ff/session.h b/lasso/id-ff/session.h
index d6189273..62fe323d 100644
--- a/lasso/id-ff/session.h
+++ b/lasso/id-ff/session.h
@@ -84,6 +84,13 @@ LASSO_EXPORT LassoNode* lasso_session_get_assertion(
LASSO_EXPORT lasso_error_t lasso_session_add_assertion(LassoSession *session,
const char *providerID, LassoNode *assertion);
+LASSO_EXPORT GList *lasso_session_get_name_ids(LassoSession *session, const gchar *providerID);
+
+LASSO_EXPORT GList *lasso_session_get_session_indexes(LassoSession *session,
+ const gchar *providerID, LassoNode *name_id);
+
+LASSO_EXPORT GList* lasso_session_get_assertion_ids(LassoSession *session, const gchar *providerID);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/id-ff/sessionprivate.h b/lasso/id-ff/sessionprivate.h
index a55bbb82..03af335a 100644
--- a/lasso/id-ff/sessionprivate.h
+++ b/lasso/id-ff/sessionprivate.h
@@ -41,11 +41,15 @@ struct _LassoSessionPrivate
GList *providerIDs;
GHashTable *status; /* hold temporary response status for sso-art */
GHashTable *assertions_by_id;
+ GHashTable *nid_and_session_indexes;
#ifdef LASSO_WSF_ENABLED
GHashTable *eprs;
#endif
};
+#define LASSO_SESSION_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), LASSO_TYPE_SESSION, LassoSessionPrivate))
+
gint lasso_session_add_status(LassoSession *session,
const char *providerID, LassoNode *status);
gint lasso_session_add_assertion_with_id(LassoSession *session,
@@ -62,6 +66,8 @@ gboolean lasso_session_is_dirty(LassoSession *session);
void lasso_session_init_provider_ids(LassoSession *session);
+gboolean lasso_session_has_slo_session(LassoSession *session, const gchar *provider_id);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/lasso.c b/lasso/lasso.c
index 98248dac..3d127f9b 100644
--- a/lasso/lasso.c
+++ b/lasso/lasso.c
@@ -95,6 +95,8 @@ gboolean lasso_flag_add_signature = TRUE;
static void lasso_flag_parse_environment_variable();
/* do not sign messages */
gboolean lasso_flag_sign_messages = TRUE;
+/* thin sessions */
+gboolean lasso_flag_thin_sessions = FALSE;
#ifndef LASSO_FLAG_ENV_VAR
#define LASSO_FLAG_ENV_VAR "LASSO_FLAG"
@@ -317,6 +319,9 @@ void lasso_set_flag(char *flag) {
lasso_flag_sign_messages = value;
continue;
}
+ if (lasso_strisequal(flag,"thin-sessions")) {
+ lasso_flag_thin_sessions = value;
+ }
} while (FALSE);
}
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 */
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 */
diff --git a/lasso/xml/saml_name_identifier.c b/lasso/xml/saml_name_identifier.c
index 1d0d1a14..a93c8f7c 100644
--- a/lasso/xml/saml_name_identifier.c
+++ b/lasso/xml/saml_name_identifier.c
@@ -98,6 +98,20 @@ lasso_saml_name_identifier_get_type()
return this_type;
}
+gboolean
+lasso_saml_name_identifier_equals(LassoSamlNameIdentifier *a,
+ LassoSamlNameIdentifier *b) {
+ if (a == NULL || b == NULL)
+ return FALSE;
+
+ if (! LASSO_IS_SAML_NAME_IDENTIFIER(a) && ! LASSO_IS_SAML_NAME_IDENTIFIER(b)) {
+ return FALSE;
+ }
+ return lasso_strisequal(a->NameQualifier, b->NameQualifier)
+ && lasso_strisequal(a->Format, b->Format)
+ && lasso_strisequal(a->content, b->content);
+}
+
/**
* lasso_saml_name_identifier_new:
*
diff --git a/lasso/xml/saml_name_identifier.h b/lasso/xml/saml_name_identifier.h
index 4902727c..ede9dbab 100644
--- a/lasso/xml/saml_name_identifier.h
+++ b/lasso/xml/saml_name_identifier.h
@@ -83,6 +83,9 @@ LASSO_EXPORT LassoSamlNameIdentifier* lasso_saml_name_identifier_new(void);
LASSO_EXPORT LassoSamlNameIdentifier* lasso_saml_name_identifier_new_from_xmlNode(
xmlNode *xmlnode);
+LASSO_EXPORT gboolean lasso_saml_name_identifier_equals(LassoSamlNameIdentifier *a,
+ LassoSamlNameIdentifier *b);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/xml/strings.h b/lasso/xml/strings.h
index 391ffb67..7c7be759 100644
--- a/lasso/xml/strings.h
+++ b/lasso/xml/strings.h
@@ -626,7 +626,7 @@
* LASSO_LIB_NAME_IDENTIFIER_FORMAT_FEDERATED:
*
* <emphasis>Federated</emphasis> name identifier constant, used in
- * #LassoNameIdentifier. It implies the name identifier belongs to
+ * #LassoSamlNameIdentifier. It implies the name identifier belongs to
* a federation established between SP and IdP.
*/
#define LASSO_LIB_NAME_IDENTIFIER_FORMAT_FEDERATED "urn:liberty:iff:nameid:federated"
@@ -634,14 +634,14 @@
/**
* LASSO_LIB_NAME_IDENTIFIER_FORMAT_ONE_TIME:
*
- * "One-time" name identifier constant, used in #LassoNameIdentifier.
+ * "One-time" name identifier constant, used in #LassoSamlNameIdentifier.
*/
#define LASSO_LIB_NAME_IDENTIFIER_FORMAT_ONE_TIME "urn:liberty:iff:nameid:one-time"
/**
* LASSO_LIB_NAME_IDENTIFIER_FORMAT_ENCRYPTED:
*
- * "Encrypted" name identifier constant, used in #LassoNameIdentifier.
+ * "Encrypted" name identifier constant, used in #LassoSamlNameIdentifier.
*/
#define LASSO_LIB_NAME_IDENTIFIER_FORMAT_ENCRYPTED "urn:liberty:iff:nameid:encrypted"
#define LASSO_LIB_NAME_IDENTIFIER_FORMAT_ENTITYID "urn:liberty:iff:nameid:entityID"
diff --git a/tests/login_tests.c b/tests/login_tests.c
index c432fe9f..c1688b02 100644
--- a/tests/login_tests.c
+++ b/tests/login_tests.c
@@ -33,7 +33,6 @@
#include "tests.h"
#include "../bindings/ghashtable.h"
-
static char*
generateIdentityProviderContextDump()
{
@@ -151,6 +150,8 @@ START_TEST(test02_serviceProviderLogin)
char *spLoginDump;
int requestType;
char *found;
+ char *artifact_message;
+ char *artifact;
serviceProviderContextDump = generateServiceProviderContextDump();
spContext = lasso_server_new_from_dump(serviceProviderContextDump);
@@ -228,6 +229,12 @@ START_TEST(test02_serviceProviderLogin)
serviceProviderId = g_strdup(LASSO_PROFILE(idpLoginContext)->remote_providerID);
fail_unless(serviceProviderId != NULL,
"lasso_profile_get_remote_providerID shouldn't return NULL");
+ if (lasso_flag_thin_sessions) {
+ /* when using thin sessions, the way artifact message is constructed changes as the
+ * session no more contains full assertions. */
+ artifact = g_strdup(lasso_profile_get_artifact(&idpLoginContext->parent));
+ artifact_message = g_strdup(lasso_profile_get_artifact_message(&idpLoginContext->parent));
+ }
/* Service provider assertion consumer */
lasso_server_destroy(spContext);
@@ -262,6 +269,10 @@ START_TEST(test02_serviceProviderLogin)
idpLoginContext = lasso_login_new(idpContext);
check_true(LASSO_IS_LOGIN(idpLoginContext));
check_good_rc(lasso_login_process_request_msg(idpLoginContext, soapRequestMsg));
+ if (lasso_flag_thin_sessions) {
+ check_str_equals(idpLoginContext->assertionArtifact, artifact);
+ lasso_profile_set_artifact_message(&idpLoginContext->parent, artifact_message);
+ }
check_good_rc(lasso_profile_set_session_from_dump(LASSO_PROFILE(idpLoginContext),
idpSessionContextDump));
check_good_rc(lasso_login_build_response_msg(idpLoginContext, serviceProviderId));
@@ -323,6 +334,8 @@ START_TEST(test03_serviceProviderLogin)
char *spIdentityContextDump;
char *spSessionDump;
int requestType;
+ char *artifact_message;
+ char *artifact;
serviceProviderContextDump = generateServiceProviderContextDump();
spContext = lasso_server_new_from_dump(serviceProviderContextDump);
@@ -366,7 +379,6 @@ START_TEST(test03_serviceProviderLogin)
1, /* authentication_result */
0 /* is_consent_obtained */
);
-
rc = lasso_login_build_assertion(idpLoginContext,
LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
"FIXME: authenticationInstant",
@@ -375,7 +387,6 @@ START_TEST(test03_serviceProviderLogin)
"FIXME: notOnOrAfter");
rc = lasso_login_build_artifact_msg(idpLoginContext, LASSO_HTTP_METHOD_REDIRECT);
fail_unless(rc == 0, "lasso_login_build_artifact_msg failed");
-
idpIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(idpLoginContext)->identity);
fail_unless(idpIdentityContextDump != NULL,
"lasso_identity_dump shouldn't return NULL");
@@ -390,6 +401,12 @@ START_TEST(test03_serviceProviderLogin)
serviceProviderId = g_strdup(LASSO_PROFILE(idpLoginContext)->remote_providerID);
fail_unless(serviceProviderId != NULL,
"lasso_profile_get_remote_providerID shouldn't return NULL");
+ if (lasso_flag_thin_sessions) {
+ /* when using thin sessions, the way artifact message is constructed changes as the
+ * session no more contains full assertions. */
+ artifact = g_strdup(lasso_profile_get_artifact(&idpLoginContext->parent));
+ artifact_message = g_strdup(lasso_profile_get_artifact_message(&idpLoginContext->parent));
+ }
/* Service provider assertion consumer */
lasso_server_destroy(spContext);
@@ -417,7 +434,10 @@ START_TEST(test03_serviceProviderLogin)
idpLoginContext = lasso_login_new(idpContext);
rc = lasso_login_process_request_msg(idpLoginContext, soapRequestMsg);
fail_unless(rc == 0, "lasso_login_process_request_msg failed");
-
+ if (lasso_flag_thin_sessions) {
+ check_str_equals(idpLoginContext->assertionArtifact, artifact);
+ lasso_profile_set_artifact_message(&idpLoginContext->parent, artifact_message);
+ }
rc = lasso_profile_set_session_from_dump(LASSO_PROFILE(idpLoginContext),
idpSessionContextDump);
fail_unless(rc == 0, "lasso_login_set_assertion_from_dump failed");