summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Peters <fpeters@entrouvert.com>2005-11-21 18:51:52 +0000
committerFrederic Peters <fpeters@entrouvert.com>2005-11-21 18:51:52 +0000
commit853f46fd9325b7f3eec0bc385c4a9bd763c031d4 (patch)
tree55a2fcb3a0432cee3d5591b89550871182fb2fb9
parentab1e605ce59bba13464c814bc224146875b170ff (diff)
downloadlasso-853f46fd9325b7f3eec0bc385c4a9bd763c031d4.tar.gz
lasso-853f46fd9325b7f3eec0bc385c4a9bd763c031d4.tar.xz
lasso-853f46fd9325b7f3eec0bc385c4a9bd763c031d4.zip
starting SAML 2 logout
-rw-r--r--lasso/id-ff/defederation.c7
-rw-r--r--lasso/id-ff/federation.c34
-rw-r--r--lasso/id-ff/federation.h2
-rw-r--r--lasso/id-ff/login.c42
-rw-r--r--lasso/id-ff/logout.c67
-rw-r--r--lasso/id-ff/logoutprivate.h43
-rw-r--r--lasso/id-ff/name_registration.c4
-rw-r--r--lasso/id-ff/profile.c16
-rw-r--r--lasso/id-ff/profile.h2
-rw-r--r--lasso/id-ff/provider.c6
-rw-r--r--lasso/id-ff/provider.h2
-rw-r--r--lasso/id-ff/session.c5
-rw-r--r--lasso/saml-2.0/Makefile.am6
-rw-r--r--lasso/saml-2.0/login.c9
-rw-r--r--lasso/saml-2.0/logout.c482
-rw-r--r--lasso/saml-2.0/logoutprivate.h49
-rw-r--r--lasso/saml-2.0/profile.c4
-rw-r--r--lasso/saml-2.0/provider.c81
-rw-r--r--lasso/saml-2.0/providerprivate.h4
-rw-r--r--lasso/xml/private.h4
-rw-r--r--lasso/xml/saml-2.0/Makefile.am4
-rw-r--r--lasso/xml/saml-2.0/samlp2_artifact_resolve.c28
-rw-r--r--lasso/xml/saml-2.0/samlp2_logout_response.c129
-rw-r--r--lasso/xml/saml-2.0/samlp2_manage_name_id_response.c129
-rw-r--r--lasso/xml/saml-2.0/samlp2_name_id_mapping_response.c28
-rw-r--r--lasso/xml/saml-2.0/samlp2_request_abstract.c11
-rw-r--r--lasso/xml/saml-2.0/samlp2_response.c28
-rw-r--r--lasso/xml/saml-2.0/samlp2_status_response.c39
-rw-r--r--lasso/xml/xml.c1
29 files changed, 1141 insertions, 125 deletions
diff --git a/lasso/id-ff/defederation.c b/lasso/id-ff/defederation.c
index fdb5cc6b..2040e1a7 100644
--- a/lasso/id-ff/defederation.c
+++ b/lasso/id-ff/defederation.c
@@ -152,6 +152,7 @@ lasso_defederation_init_notification(LassoDefederation *defederation, gchar *rem
LassoProvider *remote_provider;
LassoFederation *federation;
LassoSamlNameIdentifier *nameIdentifier;
+ LassoNode *nameIdentifier_n;
g_return_val_if_fail(LASSO_IS_DEFEDERATION(defederation),
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
@@ -183,10 +184,11 @@ lasso_defederation_init_notification(LassoDefederation *defederation, gchar *rem
}
/* get the nameIdentifier to send the federation termination notification */
- nameIdentifier = lasso_profile_get_nameIdentifier(profile);
+ nameIdentifier_n = lasso_profile_get_nameIdentifier(profile);
if (nameIdentifier == NULL) {
return critical_error(LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND);
}
+ nameIdentifier = LASSO_SAML_NAME_IDENTIFIER(nameIdentifier_n);
if (federation->local_nameIdentifier) {
profile->nameIdentifier = g_object_ref(federation->local_nameIdentifier);
@@ -393,7 +395,8 @@ lasso_defederation_validate_notification(LassoDefederation *defederation)
return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
}
- if (lasso_federation_verify_name_identifier(federation, nameIdentifier) == FALSE) {
+ if (lasso_federation_verify_name_identifier(federation,
+ LASSO_NODE(nameIdentifier)) == FALSE) {
return critical_error(LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND);
}
diff --git a/lasso/id-ff/federation.c b/lasso/id-ff/federation.c
index dbcc2a71..2f7cbbd9 100644
--- a/lasso/id-ff/federation.c
+++ b/lasso/id-ff/federation.c
@@ -23,6 +23,9 @@
*/
#include <lasso/id-ff/federation.h>
+#include <lasso/id-ff/provider.h>
+
+#include <lasso/xml/saml-2.0/saml2_name_id.h>
struct _LassoFederationPrivate
{
@@ -98,25 +101,44 @@ lasso_federation_destroy(LassoFederation *federation)
**/
gboolean
lasso_federation_verify_name_identifier(LassoFederation *federation,
- LassoSamlNameIdentifier *name_identifier)
+ LassoNode *name_identifier)
{
- char *s;
+ LassoProtocolConformance conformance;
+ char *s, *content;
g_return_val_if_fail(LASSO_IS_FEDERATION(federation), FALSE);
g_return_val_if_fail(LASSO_IS_NODE(name_identifier), FALSE);
+ if (LASSO_IS_SAML_NAME_IDENTIFIER(name_identifier)) {
+ conformance = LASSO_PROTOCOL_LIBERTY_1_2;
+ content = LASSO_SAML_NAME_IDENTIFIER(name_identifier)->content;
+ } else if (LASSO_IS_SAML2_NAME_ID(name_identifier)) {
+ conformance = LASSO_PROTOCOL_SAML_2_0;
+ content = LASSO_SAML2_NAME_ID(name_identifier)->content;
+ } else {
+ return FALSE;
+ }
+
/* verify local name identifier */
if (federation->local_nameIdentifier != NULL) {
- s = LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier)->content;
- if (strcmp(s, name_identifier->content) == 0) {
+ if (conformance == LASSO_PROTOCOL_LIBERTY_1_2) {
+ s = LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier)->content;
+ } else {
+ s = LASSO_SAML2_NAME_ID(federation->local_nameIdentifier)->content;
+ }
+ if (strcmp(s, content) == 0) {
return TRUE;
}
}
/* verify remote name identifier */
if (federation->remote_nameIdentifier != NULL) {
- s = LASSO_SAML_NAME_IDENTIFIER(federation->remote_nameIdentifier)->content;
- if (strcmp(s, name_identifier->content) == 0) {
+ if (conformance == LASSO_PROTOCOL_LIBERTY_1_2) {
+ s = LASSO_SAML_NAME_IDENTIFIER(federation->remote_nameIdentifier)->content;
+ } else {
+ s = LASSO_SAML2_NAME_ID(federation->remote_nameIdentifier)->content;
+ }
+ if (strcmp(s, content) == 0) {
return TRUE;
}
}
diff --git a/lasso/id-ff/federation.h b/lasso/id-ff/federation.h
index 7b113d0b..e4861503 100644
--- a/lasso/id-ff/federation.h
+++ b/lasso/id-ff/federation.h
@@ -73,7 +73,7 @@ LASSO_EXPORT void lasso_federation_build_local_name_identifier(LassoFederation *
LASSO_EXPORT void lasso_federation_destroy(LassoFederation *federation);
LASSO_EXPORT gboolean lasso_federation_verify_name_identifier(
- LassoFederation *federation, LassoSamlNameIdentifier *name_identifier);
+ LassoFederation *federation, LassoNode *name_identifier);
#ifdef __cplusplus
}
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 69fad979..489e6afd 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -218,8 +218,7 @@ lasso_login_build_assertion(LassoLogin *login,
if (profile->identity == NULL)
return LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND;
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_build_assertion(login,
authenticationMethod, authenticationInstant,
reauthenticateOnOrAfter, notBefore, notOnOrAfter);
@@ -582,8 +581,7 @@ lasso_login_accept_sso(LassoLogin *login)
if (profile->response == NULL)
return LASSO_ERROR_UNDEFINED;
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_accept_sso(login);
}
@@ -671,8 +669,7 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_build_artifact_msg(login, http_method);
}
@@ -803,8 +800,7 @@ lasso_login_build_authn_request_msg(LassoLogin *login)
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_build_authn_request_msg(login, remote_provider);
}
@@ -964,8 +960,7 @@ lasso_login_build_request_msg(LassoLogin *login)
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_build_request_msg(login);
}
@@ -1007,8 +1002,7 @@ lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
g_return_val_if_fail(LASSO_IS_LOGIN(login), -1);
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) ==
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_build_response_msg(login, remote_providerID);
}
@@ -1142,8 +1136,7 @@ lasso_login_init_authn_request(LassoLogin *login, const gchar *remote_providerID
if (LASSO_IS_PROVIDER(remote_provider) == FALSE)
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_init_authn_request(login, remote_provider, http_method);
}
@@ -1213,8 +1206,7 @@ lasso_login_init_request(LassoLogin *login, gchar *response_msg,
g_return_val_if_fail(response_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_init_request(login, response_msg,
response_http_method);
}
@@ -1328,8 +1320,7 @@ lasso_login_must_ask_for_consent(LassoLogin *login)
{
LassoProfile *profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_must_ask_for_consent(login);
}
@@ -1359,8 +1350,7 @@ lasso_login_must_authenticate(LassoLogin *login)
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_must_authenticate(login);
}
@@ -1410,8 +1400,7 @@ lasso_login_process_authn_request_msg(LassoLogin *login, const char *authn_reque
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_process_authn_request_msg(login, authn_request_msg);
}
@@ -1590,8 +1579,7 @@ lasso_login_process_request_msg(LassoLogin *login, gchar *request_msg)
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
g_return_val_if_fail(request_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_process_request_msg(login, request_msg);
}
@@ -1632,8 +1620,7 @@ lasso_login_process_response_msg(LassoLogin *login, gchar *response_msg)
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_process_response_msg(login, response_msg);
}
@@ -1916,8 +1903,7 @@ lasso_login_validate_request_msg(LassoLogin *login, gboolean authentication_resu
profile = LASSO_PROFILE(login);
- if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
- LASSO_PROTOCOL_SAML_2_0) {
+ IF_SAML2(profile) {
return lasso_saml20_login_validate_request_msg(login,
authentication_result, is_consent_obtained);
}
diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c
index f2454220..6a872498 100644
--- a/lasso/id-ff/logout.c
+++ b/lasso/id-ff/logout.c
@@ -22,19 +22,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <lasso/xml/lib_authentication_statement.h>
+
#include <lasso/id-ff/logout.h>
+#include <lasso/id-ff/logoutprivate.h>
#include <lasso/id-ff/profileprivate.h>
#include <lasso/id-ff/providerprivate.h>
#include <lasso/id-ff/sessionprivate.h>
-#include <lasso/xml/lib_authentication_statement.h>
-
-struct _LassoLogoutPrivate
-{
- gboolean dispose_has_run;
- gboolean all_soap;
-};
+#include <lasso/saml-2.0/logoutprivate.h>
static void check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile);
@@ -86,6 +83,10 @@ lasso_logout_build_request_msg(LassoLogout *logout)
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
+ IF_SAML2(profile) {
+ return lasso_saml20_logout_build_request_msg(logout, remote_provider);
+ }
+
/* build the logout request message */
if (logout->initial_http_request_method == LASSO_HTTP_METHOD_SOAP) {
/* build the logout request message */
@@ -158,10 +159,14 @@ lasso_logout_build_response_msg(LassoLogout *logout)
LassoProvider *provider;
gchar *url, *query;
- g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
+ g_return_val_if_fail(LASSO_IS_LOGOUT(logout), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
profile = LASSO_PROFILE(logout);
+ IF_SAML2(profile) {
+ return lasso_saml20_logout_build_response_msg(logout);
+ }
+
if (profile->response == NULL) {
if (profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
profile->response = lasso_lib_logout_response_new_full(
@@ -193,7 +198,7 @@ lasso_logout_build_response_msg(LassoLogout *logout)
if (profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
profile->msg_url = NULL;
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->private_key_file =
- profile->server->private_key;
+ g_strdup(profile->server->private_key);
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->certificate_file =
profile->server->certificate;
profile->msg_body = lasso_node_export_to_soap(profile->response);
@@ -212,7 +217,7 @@ lasso_logout_build_response_msg(LassoLogout *logout)
if (url == NULL) {
return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
}
- query = lasso_node_export_to_query(LASSO_NODE(profile->response),
+ query = lasso_node_export_to_query(profile->response,
profile->server->signature_method,
profile->server->private_key);
if (query == NULL) {
@@ -293,7 +298,7 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
LassoProfile *profile;
LassoProvider *remote_provider;
LassoSamlNameIdentifier *nameIdentifier;
- LassoNode *assertion_n;
+ LassoNode *assertion_n, *name_identifier_n;
LassoSamlAssertion *assertion;
LassoFederation *federation = NULL;
gboolean is_http_redirect_get_method = FALSE;
@@ -321,6 +326,17 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
}
+ /* get the provider */
+ remote_provider = g_hash_table_lookup(
+ profile->server->providers, profile->remote_providerID);
+ if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
+ return critical_error(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) {
@@ -353,10 +369,11 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
}
- nameIdentifier = lasso_profile_get_nameIdentifier(profile);
- if (nameIdentifier == NULL) {
+ 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) {
profile->nameIdentifier = g_object_ref(federation->local_nameIdentifier);
} else {
@@ -366,13 +383,6 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
profile->nameIdentifier = g_object_ref(nameIdentifier);
}
- /* get the provider */
- remote_provider = g_hash_table_lookup(
- profile->server->providers, profile->remote_providerID);
- if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
- return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
- }
-
/* get / verify http method */
if (http_method == LASSO_HTTP_METHOD_ANY) {
http_method = lasso_provider_get_first_http_method(
@@ -464,7 +474,8 @@ lasso_logout_init_request(LassoLogout *logout, char *remote_providerID,
*
* Return value: 0 on success; or a negative value otherwise.
**/
-gint lasso_logout_process_request_msg(LassoLogout *logout, char *request_msg)
+gint
+lasso_logout_process_request_msg(LassoLogout *logout, char *request_msg)
{
LassoProfile *profile;
LassoProvider *remote_provider;
@@ -475,6 +486,10 @@ gint lasso_logout_process_request_msg(LassoLogout *logout, char *request_msg)
profile = LASSO_PROFILE(logout);
+ IF_SAML2(profile) {
+ return lasso_saml20_logout_process_request_msg(logout, request_msg);
+ }
+
profile->request = lasso_lib_logout_request_new();
format = lasso_node_init_from_message(LASSO_NODE(profile->request), request_msg);
if (format == LASSO_MESSAGE_FORMAT_UNKNOWN || format == LASSO_MESSAGE_FORMAT_ERROR) {
@@ -748,6 +763,10 @@ lasso_logout_validate_request(LassoLogout *logout)
profile = LASSO_PROFILE(logout);
+ IF_SAML2(profile) {
+ return lasso_saml20_logout_validate_request(logout);
+ }
+
/* verify logout request */
if (LASSO_IS_LIB_LOGOUT_REQUEST(profile->request) == FALSE)
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
@@ -830,7 +849,8 @@ lasso_logout_validate_request(LassoLogout *logout)
return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
}
- if (lasso_federation_verify_name_identifier(federation, nameIdentifier) == FALSE) {
+ if (lasso_federation_verify_name_identifier(federation,
+ LASSO_NODE(nameIdentifier)) == FALSE) {
message(G_LOG_LEVEL_WARNING, "No name identifier for %s",
profile->remote_providerID);
lasso_profile_set_response_status(profile,
@@ -898,7 +918,8 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
-static void check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile)
+static void
+check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile)
{
GList *supported_profiles;
LassoSamlAssertion *assertion;
diff --git a/lasso/id-ff/logoutprivate.h b/lasso/id-ff/logoutprivate.h
new file mode 100644
index 00000000..85793234
--- /dev/null
+++ b/lasso/id-ff/logoutprivate.h
@@ -0,0 +1,43 @@
+/* $Id$
+ *
+ * Lasso - A free implementation of the Liberty Alliance specifications.
+ *
+ * Copyright (C) 2004, 2005 Entr'ouvert
+ * http://lasso.entrouvert.org
+ *
+ * Authors: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __LASSO_LOGOUT_PRIVATE_H__
+#define __LASSO_LOGOUT_PRIVATE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+struct _LassoLogoutPrivate
+{
+ gboolean dispose_has_run;
+ gboolean all_soap;
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LASSO_LOGOUT_PRIVATE_H__ */
diff --git a/lasso/id-ff/name_registration.c b/lasso/id-ff/name_registration.c
index 33a20d09..ebb733c2 100644
--- a/lasso/id-ff/name_registration.c
+++ b/lasso/id-ff/name_registration.c
@@ -575,8 +575,8 @@ lasso_name_registration_validate_request(LassoNameRegistration *name_registratio
return LASSO_ERROR_UNDEFINED;
}
- if (lasso_federation_verify_name_identifier(federation,
- request->OldProvidedNameIdentifier) == FALSE) {
+ if (lasso_federation_verify_name_identifier(federation, LASSO_NODE(
+ request->OldProvidedNameIdentifier)) == FALSE) {
message(G_LOG_LEVEL_CRITICAL, "No name identifier");
return LASSO_ERROR_UNDEFINED;
}
diff --git a/lasso/id-ff/profile.c b/lasso/id-ff/profile.c
index 864a68c0..7486d0df 100644
--- a/lasso/id-ff/profile.c
+++ b/lasso/id-ff/profile.c
@@ -39,16 +39,16 @@
/**
* lasso_profile_get_nameIdentifier:
- * @profile: a #LassoProifle
+ * @profile: a #LassoProfile
*
* Looks up appropriate federation in object and gets the service provider name
- * identifier.
+ * identifier (which is actually a #LassoSamlNameIdentifier in ID-FF 1.2 and
+ * #LassoSaml2NameID in SAML 2.0).
*
- * Return value: the name identifier or NULL if none was found. The
- * #LassoSamlNameIdentifier object is internally allocated and must not be
- * freed by the caller.
+ * Return value: the name identifier or NULL if none was found. The #LassoNode
+ * object is internally allocated and must not be * freed by the caller.
**/
-LassoSamlNameIdentifier*
+LassoNode*
lasso_profile_get_nameIdentifier(LassoProfile *profile)
{
LassoProvider *remote_provider;
@@ -71,9 +71,9 @@ lasso_profile_get_nameIdentifier(LassoProfile *profile)
return NULL;
if (federation->remote_nameIdentifier)
- return LASSO_SAML_NAME_IDENTIFIER(federation->remote_nameIdentifier);
+ return federation->remote_nameIdentifier;
- return LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier);
+ return federation->local_nameIdentifier;
}
/**
diff --git a/lasso/id-ff/profile.h b/lasso/id-ff/profile.h
index de281b5b..62e303c2 100644
--- a/lasso/id-ff/profile.h
+++ b/lasso/id-ff/profile.h
@@ -131,7 +131,7 @@ LASSO_EXPORT gboolean lasso_profile_is_session_dirty(LassoProfile *profile);
LASSO_EXPORT gint lasso_profile_set_identity_from_dump(LassoProfile *profile, const gchar *dump);
LASSO_EXPORT gint lasso_profile_set_session_from_dump(LassoProfile *profile, const gchar *dump);
-LASSO_EXPORT LassoSamlNameIdentifier* lasso_profile_get_nameIdentifier(LassoProfile *profile);
+LASSO_EXPORT LassoNode* lasso_profile_get_nameIdentifier(LassoProfile *profile);
LASSO_EXPORT char* lasso_profile_get_artifact(LassoProfile *profile);
LASSO_EXPORT char* lasso_profile_get_artifact_message(LassoProfile *profile);
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index 650e87ed..291d0542 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -234,6 +234,12 @@ lasso_provider_accept_http_method(LassoProvider *provider, LassoProvider *remote
LassoProviderRole initiating_role;
char *protocol_profile;
+ if (provider->private_data->conformance == LASSO_PROTOCOL_SAML_2_0) {
+ return lasso_saml20_provider_accept_http_method(
+ provider, remote_provider, protocol_type,
+ http_method, initiate_profile);
+ }
+
initiating_role = remote_provider->role;
if (remote_provider->role == LASSO_PROVIDER_ROLE_SP) {
provider->role = LASSO_PROVIDER_ROLE_IDP;
diff --git a/lasso/id-ff/provider.h b/lasso/id-ff/provider.h
index 9cad9124..c41e845b 100644
--- a/lasso/id-ff/provider.h
+++ b/lasso/id-ff/provider.h
@@ -87,7 +87,7 @@ typedef enum {
* Liberty Metadata Type.
**/
typedef enum {
- LASSO_MD_PROTOCOL_TYPE_FEDERATION_TERMINATION = 0,
+ LASSO_MD_PROTOCOL_TYPE_FEDERATION_TERMINATION,
LASSO_MD_PROTOCOL_TYPE_NAME_IDENTIFIER_MAPPING,
LASSO_MD_PROTOCOL_TYPE_REGISTER_NAME_IDENTIFIER,
LASSO_MD_PROTOCOL_TYPE_SINGLE_LOGOUT,
diff --git a/lasso/id-ff/session.c b/lasso/id-ff/session.c
index 2089956a..4432a621 100644
--- a/lasso/id-ff/session.c
+++ b/lasso/id-ff/session.c
@@ -333,8 +333,9 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
while (n && n->type != XML_ELEMENT_NODE) n = n->next;
if (n) {
- LassoLibAssertion *assertion;
- assertion = LASSO_LIB_ASSERTION(lasso_node_new_from_xmlNode(n));
+ LassoNode *assertion;
+
+ assertion = lasso_node_new_from_xmlNode(n);
g_hash_table_insert(session->assertions,
xmlGetProp(t, (xmlChar*)"RemoteProviderID"),
assertion);
diff --git a/lasso/saml-2.0/Makefile.am b/lasso/saml-2.0/Makefile.am
index 49e4f418..ccd913ab 100644
--- a/lasso/saml-2.0/Makefile.am
+++ b/lasso/saml-2.0/Makefile.am
@@ -12,12 +12,14 @@ liblasso_saml_20_la_SOURCES = \
federation.c \
profile.c \
provider.c \
- login.c
+ login.c \
+ logout.c
lasso_private_h_sources = \
federationprivate.h \
profileprivate.h \
providerprivate.h \
- loginprivate.h
+ loginprivate.h \
+ logoutprivate.h
EXTRA_DIST = $(lasso_private_h_sources)
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 6315343d..836c5dc6 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -133,9 +133,9 @@ lasso_saml20_login_build_authn_request_msg(LassoLogin *login, LassoProvider *rem
/* POST and Artifact-GET|POST */
if (must_sign) {
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file =
- profile->server->private_key;
+ g_strdup(profile->server->private_key);
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file =
- profile->server->certificate;
+ g_strdup(profile->server->certificate);
}
if (login->http_method == LASSO_HTTP_METHOD_POST) {
@@ -189,6 +189,7 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
LASSO_PROVIDER(profile->server)->ProviderID));
response->IssueInstant = lasso_get_current_time();
response->InResponseTo = g_strdup(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
+ /* XXX: adds signature */
return 0;
}
@@ -485,9 +486,9 @@ lasso_saml20_login_build_request_msg(LassoLogin *login)
profile->msg_body = lasso_node_export_to_soap(profile->request);
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file =
- profile->server->private_key;
+ g_strdup(profile->server->private_key);
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file =
- profile->server->certificate;
+ g_strdup(profile->server->certificate);
profile->msg_body = lasso_node_export_to_soap(profile->request);
remote_provider = g_hash_table_lookup(profile->server->providers,
diff --git a/lasso/saml-2.0/logout.c b/lasso/saml-2.0/logout.c
new file mode 100644
index 00000000..efe96108
--- /dev/null
+++ b/lasso/saml-2.0/logout.c
@@ -0,0 +1,482 @@
+/* $Id$
+ *
+ * Lasso - A free implementation of the Liberty Alliance specifications.
+ *
+ * Copyright (C) 2004, 2005 Entr'ouvert
+ * http://lasso.entrouvert.org
+ *
+ * Authors: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <lasso/saml-2.0/providerprivate.h>
+#include <lasso/saml-2.0/logoutprivate.h>
+#include <lasso/saml-2.0/profileprivate.h>
+#include <lasso/saml-2.0/federationprivate.h>
+
+#include <lasso/id-ff/providerprivate.h>
+#include <lasso/id-ff/logout.h>
+#include <lasso/id-ff/logoutprivate.h>
+#include <lasso/id-ff/identityprivate.h>
+#include <lasso/id-ff/sessionprivate.h>
+#include <lasso/id-ff/profileprivate.h>
+
+#include <lasso/xml/saml-2.0/samlp2_logout_request.h>
+#include <lasso/xml/saml-2.0/samlp2_logout_response.h>
+#include <lasso/xml/saml-2.0/saml2_assertion.h>
+
+static void check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile);
+
+int
+lasso_saml20_logout_init_request(LassoLogout *logout, LassoProvider *remote_provider,
+ LassoHttpMethod http_method)
+{
+ LassoProfile *profile = LASSO_PROFILE(logout);
+ LassoNode *assertion_n, *name_id_n;
+ LassoSaml2Assertion *assertion;
+ LassoSaml2NameID *name_id;
+ LassoFederation *federation;
+ LassoSession *session;
+ LassoSamlp2RequestAbstract *request;
+
+ /* 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) {
+ message(G_LOG_LEVEL_CRITICAL, "Assertion not found");
+ return LASSO_ERROR_UNDEFINED;
+ }
+
+ assertion = LASSO_SAML2_ASSERTION(assertion_n);
+
+ if (assertion->Subject == NULL) {
+ return LASSO_ERROR_UNDEFINED;
+ }
+
+ name_id = assertion->Subject->NameID;
+ if (name_id->Format && strcmp(name_id->Format,
+ LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0) {
+ 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_id_n = lasso_profile_get_nameIdentifier(profile);
+ if (name_id_n == NULL) {
+ return critical_error(LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND);
+ }
+ if (federation->local_nameIdentifier) {
+ profile->nameIdentifier = g_object_ref(federation->local_nameIdentifier);
+ } else {
+ profile->nameIdentifier = g_object_ref(name_id_n);
+ }
+
+ } else {
+ profile->nameIdentifier = g_object_ref(name_id);
+ }
+
+ if (http_method == LASSO_HTTP_METHOD_ANY) {
+ http_method = lasso_provider_get_first_http_method(
+ LASSO_PROVIDER(profile->server),
+ remote_provider,
+ LASSO_MD_PROTOCOL_TYPE_SINGLE_LOGOUT);
+ } else {
+ if (lasso_provider_accept_http_method(LASSO_PROVIDER(profile->server),
+ remote_provider,
+ LASSO_MD_PROTOCOL_TYPE_SINGLE_LOGOUT,
+ http_method,
+ TRUE) == FALSE) {
+ if (http_method == LASSO_HTTP_METHOD_REDIRECT) {
+ /* it was probably used as last resort, and
+ * failed, since the remote provider doesn't
+ * support any logout. remove assertion
+ * unconditionnaly. */
+ lasso_session_remove_assertion(profile->session,
+ profile->remote_providerID);
+ if (logout->initial_remote_providerID && logout->initial_request) {
+ g_free(profile->remote_providerID);
+ profile->remote_providerID = g_strdup(
+ logout->initial_remote_providerID);
+ /* XXX: create response
+ profile->response = lasso_lib_logout_response_new_full(
+ LASSO_PROVIDER(profile->server)->ProviderID,
+ LASSO_SAML_STATUS_CODE_SUCCESS,
+ LASSO_LIB_LOGOUT_REQUEST(logout->initial_request),
+ LASSO_SIGNATURE_TYPE_NONE,
+ 0);
+ */
+ }
+ }
+ return LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE;
+ }
+ }
+
+ /* free profile->request if it was already set */
+ if (LASSO_IS_NODE(profile->request)) {
+ lasso_node_destroy(profile->request);
+ profile->request = NULL;
+ }
+
+ profile->request = lasso_samlp2_logout_request_new();
+ request = LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request);
+ request->ID = lasso_build_unique_id(32);
+ request->Version = g_strdup("2.0");
+ request->Issuer = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
+ LASSO_PROVIDER(profile->server)->ProviderID));
+ request->IssueInstant = lasso_get_current_time();
+
+ LASSO_SAMLP2_LOGOUT_REQUEST(request)->NameID = g_object_ref(profile->nameIdentifier);
+
+ /* XXX: SessionIndex */
+
+ logout->initial_http_request_method = http_method;
+
+ return 0;
+}
+
+
+int
+lasso_saml20_logout_build_request_msg(LassoLogout *logout, LassoProvider *remote_provider)
+{
+ LassoProfile *profile = LASSO_PROFILE(logout);
+
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file =
+ g_strdup(profile->server->private_key);
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file =
+ g_strdup(profile->server->certificate);
+
+ if (logout->initial_http_request_method == LASSO_HTTP_METHOD_SOAP) {
+ profile->msg_url = lasso_provider_get_metadata_one(remote_provider,
+ "SingleLogoutService SOAP");
+ profile->msg_body = lasso_node_export_to_soap(profile->request);
+ return 0;
+ }
+
+ if (logout->initial_http_request_method == LASSO_HTTP_METHOD_REDIRECT) {
+ char *url, *query;
+ url = lasso_provider_get_metadata_one(remote_provider,
+ "SingleLogoutService HTTP-Redirect");
+ if (url == NULL) {
+ return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
+ }
+ query = lasso_node_export_to_query(profile->request,
+ profile->server->signature_method,
+ profile->server->private_key);
+ if (query == NULL) {
+ g_free(url);
+ return critical_error(LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
+ }
+ profile->msg_url = g_strdup_printf("%s?%s", url, query);
+ return 0;
+ }
+
+ /* XXX: artifact support */
+
+ return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
+}
+
+int
+lasso_saml20_logout_process_request_msg(LassoLogout *logout, char *request_msg)
+{
+ LassoProfile *profile = LASSO_PROFILE(logout);
+ LassoProvider *remote_provider;
+ LassoMessageFormat format;
+
+ profile->request = lasso_samlp2_logout_request_new();
+ format = lasso_node_init_from_message(LASSO_NODE(profile->request), request_msg);
+ if (format == LASSO_MESSAGE_FORMAT_UNKNOWN || format == LASSO_MESSAGE_FORMAT_ERROR) {
+ return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
+ }
+
+
+ remote_provider = g_hash_table_lookup(profile->server->providers,
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->Issuer->content);
+ if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
+ return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
+ }
+
+ /* verify signatures */
+ profile->signature_status = lasso_provider_verify_signature(
+ remote_provider, request_msg, "ID", format);
+
+ if (format == LASSO_MESSAGE_FORMAT_SOAP)
+ profile->http_request_method = LASSO_HTTP_METHOD_SOAP;
+ if (format == LASSO_MESSAGE_FORMAT_QUERY)
+ profile->http_request_method = LASSO_HTTP_METHOD_REDIRECT;
+
+ profile->nameIdentifier = g_object_ref(
+ LASSO_SAMLP2_LOGOUT_REQUEST(profile->request)->NameID);
+
+ return profile->signature_status;
+}
+
+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;
+ LassoFederation *federation;
+
+ if (LASSO_IS_SAMLP2_LOGOUT_REQUEST(profile->request) == FALSE)
+ return LASSO_PROFILE_ERROR_MISSING_REQUEST;
+
+ profile->remote_providerID = g_strdup(
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->Issuer->content);
+
+ /* get the provider */
+ remote_provider = g_hash_table_lookup(profile->server->providers,
+ profile->remote_providerID);
+ if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
+ return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
+ }
+
+ if (profile->response) {
+ lasso_node_destroy(profile->response);
+ }
+
+ profile->response = lasso_samlp2_logout_response_new();
+ response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
+ response->ID = lasso_build_unique_id(32);
+ response->Version = g_strdup("2.0");
+ response->Issuer = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
+ LASSO_PROVIDER(profile->server)->ProviderID));
+ response->IssueInstant = lasso_get_current_time();
+ response->InResponseTo = g_strdup(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
+
+ response->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
+ if (profile->server->certificate) {
+ response->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
+ } else {
+ response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
+ }
+ response->private_key_file = g_strdup(profile->server->private_key);
+ response->certificate_file = g_strdup(profile->server->certificate);
+
+ /* verify signature status */
+ if (profile->signature_status != 0) {
+ /* XXX: which SAML2 Status Code ? */
+ lasso_profile_set_response_status(profile,
+ LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
+ return profile->signature_status;
+ }
+
+ /* Get the name identifier */
+ name_id = LASSO_SAMLP2_LOGOUT_REQUEST(profile->request)->NameID;
+ if (name_id == NULL) {
+ message(G_LOG_LEVEL_CRITICAL, "Name identifier not found in logout request");
+ /* XXX: which status code in SAML 2.0 ? */
+ lasso_profile_set_response_status(
+ profile, LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
+ return LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
+ }
+
+ if (profile->session == NULL) {
+ lasso_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+ return critical_error(LASSO_PROFILE_ERROR_SESSION_NOT_FOUND);
+ }
+
+ /* verify authentication */
+ assertion_n = lasso_session_get_assertion(profile->session, profile->remote_providerID);
+ if (assertion_n == NULL) {
+ message(G_LOG_LEVEL_WARNING, "%s has no assertion", profile->remote_providerID);
+ lasso_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+ return LASSO_ERROR_UNDEFINED;
+ }
+
+ assertion = LASSO_SAML2_ASSERTION(assertion_n);
+
+ /* If name identifier is federated, then verify federation */
+ if (strcmp(name_id->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0) {
+ if (LASSO_IS_IDENTITY(profile->identity) == FALSE) {
+ /* XXX: which SAML 2 status code ? */
+ lasso_profile_set_response_status(profile,
+ LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
+ return critical_error(LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND);
+ }
+ federation = g_hash_table_lookup(profile->identity->federations,
+ profile->remote_providerID);
+ if (LASSO_IS_FEDERATION(federation) == FALSE) {
+ /* XXX: which status code in SAML 2 ? */
+ lasso_profile_set_response_status(profile,
+ LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
+ return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
+ }
+
+ if (lasso_federation_verify_name_identifier(federation,
+ LASSO_NODE(name_id)) == FALSE) {
+ message(G_LOG_LEVEL_WARNING, "No name identifier for %s",
+ profile->remote_providerID);
+ lasso_profile_set_response_status(profile,
+ LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
+ return LASSO_ERROR_UNDEFINED;
+ }
+ }
+
+ /* if SOAP request method at IDP then verify all the remote service providers support
+ SOAP protocol profile.
+ If one remote authenticated principal service provider doesn't support SOAP
+ then return UnsupportedProfile to original service provider */
+ if (remote_provider->role == LASSO_PROVIDER_ROLE_SP &&
+ profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
+
+ logout->private_data->all_soap = TRUE;
+ g_hash_table_foreach(profile->server->providers,
+ (GHFunc)check_soap_support, profile);
+
+ if (logout->private_data->all_soap == FALSE) {
+ lasso_profile_set_response_status(profile,
+ LASSO_LIB_STATUS_CODE_UNSUPPORTED_PROFILE);
+ return LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE;
+ }
+ }
+
+ /* authentication is ok, federation is ok, propagation support is ok, remove assertion */
+ lasso_session_remove_assertion(profile->session, profile->remote_providerID);
+
+ /* if at IDP and nb sp logged > 1, then backup remote provider id,
+ * request and response
+ */
+ if (remote_provider->role == LASSO_PROVIDER_ROLE_SP &&
+ g_hash_table_size(profile->session->assertions) >= 1) {
+ logout->initial_remote_providerID = profile->remote_providerID;
+ logout->initial_request = LASSO_NODE(profile->request);
+ logout->initial_response = LASSO_NODE(profile->response);
+
+ profile->remote_providerID = NULL;
+ profile->request = NULL;
+ profile->response = NULL;
+ }
+
+ return 0;
+
+
+}
+
+static void
+check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile)
+{
+ 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 (assertion_n == NULL)
+ return; /* not authenticated with this provider */
+ assertion = LASSO_SAML2_ASSERTION(assertion_n);
+
+ supported_profiles = lasso_provider_get_metadata_list(provider,
+ "SingleLogoutService SOAP");
+
+ if (supported_profiles)
+ return; /* provider support profile */
+
+ LASSO_LOGOUT(profile)->private_data->all_soap = FALSE;
+}
+
+int
+lasso_saml20_logout_build_response_msg(LassoLogout *logout)
+{
+ LassoProfile *profile = LASSO_PROFILE(logout);
+ LassoSamlp2StatusResponse *response;
+ LassoProvider *provider;
+ char *url, *query;
+
+ if (profile->response == NULL) {
+ /* no response set here means request denied */
+ profile->response = lasso_samlp2_logout_response_new();
+ response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
+ response->ID = lasso_build_unique_id(32);
+ response->Version = g_strdup("2.0");
+ response->Issuer = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
+ LASSO_PROVIDER(profile->server)->ProviderID));
+ response->IssueInstant = lasso_get_current_time();
+ response->InResponseTo = g_strdup(
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
+ lasso_profile_set_response_status(profile,
+ LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+
+ response->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
+ if (profile->server->certificate) {
+ response->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
+ } else {
+ response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
+ }
+ response->private_key_file = g_strdup(profile->server->private_key);
+ response->certificate_file = g_strdup(profile->server->certificate);
+ }
+
+ if (profile->remote_providerID == NULL || profile->response == NULL) {
+ /* no remote provider id set or no response set, this means
+ * this function got called before validate_request, probably
+ * because there were no active session */
+ return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
+ }
+
+ /* build logout response message */
+ if (profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
+ profile->msg_url = NULL;
+ profile->msg_body = lasso_node_export_to_soap(profile->response);
+ return 0;
+ }
+
+ if (profile->http_request_method == LASSO_HTTP_METHOD_REDIRECT) {
+ /* get the provider */
+ provider = g_hash_table_lookup(profile->server->providers,
+ profile->remote_providerID);
+ if (provider == NULL) {
+ return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
+ }
+
+ url = lasso_provider_get_metadata_one(provider,
+ "SingleLogoutService HTTP-Redirect ResponseLocation");
+ if (url == NULL) {
+ url = lasso_provider_get_metadata_one(provider,
+ "SingleLogoutService HTTP-Redirect");
+ if (url == NULL) {
+ return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
+ }
+ }
+ query = lasso_node_export_to_query(LASSO_NODE(profile->response),
+ profile->server->signature_method,
+ profile->server->private_key);
+ if (query == NULL) {
+ g_free(url);
+ return critical_error(LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
+ }
+ profile->msg_url = g_strdup_printf("%s?%s", url, query);
+ profile->msg_body = NULL;
+ g_free(url);
+ g_free(query);
+ return 0;
+ }
+
+ return LASSO_PROFILE_ERROR_MISSING_REQUEST;
+
+
+}
+
diff --git a/lasso/saml-2.0/logoutprivate.h b/lasso/saml-2.0/logoutprivate.h
new file mode 100644
index 00000000..e4cd0e2f
--- /dev/null
+++ b/lasso/saml-2.0/logoutprivate.h
@@ -0,0 +1,49 @@
+/* $Id$
+ *
+ * Lasso - A free implementation of the Liberty Alliance specifications.
+ *
+ * Copyright (C) 2004, 2005 Entr'ouvert
+ * http://lasso.entrouvert.org
+ *
+ * Authors: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __LASSO_SAML20_LOGOUT_PRIVATE_H__
+#define __LASSO_SAML20_LOGOUT_PRIVATE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <lasso/id-ff/logout.h>
+
+int lasso_saml20_logout_init_request(LassoLogout *logout,
+ LassoProvider *remote_provider, LassoHttpMethod http_method);
+
+int lasso_saml20_logout_build_request_msg(LassoLogout *logout, LassoProvider *remote_provider);
+
+int lasso_saml20_logout_process_request_msg(LassoLogout *logout, char *request_msg);
+
+int lasso_saml20_logout_validate_request(LassoLogout *logout);
+
+int lasso_saml20_logout_build_response_msg(LassoLogout *logout);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LASSO_SAML20_LOGOUT_PRIVATE_H__ */
diff --git a/lasso/saml-2.0/profile.c b/lasso/saml-2.0/profile.c
index f6041e4b..24d88b86 100644
--- a/lasso/saml-2.0/profile.c
+++ b/lasso/saml-2.0/profile.c
@@ -250,8 +250,8 @@ lasso_saml20_profile_build_artifact_response(LassoProfile *profile)
} else {
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
}
- response->private_key_file = profile->server->private_key;
- response->certificate_file = profile->server->certificate;
+ response->private_key_file = g_strdup(profile->server->private_key);
+ response->certificate_file = g_strdup(profile->server->certificate);
profile->response = LASSO_NODE(response);
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_SUCCESS);
diff --git a/lasso/saml-2.0/provider.c b/lasso/saml-2.0/provider.c
index 3a473cf5..aa6afb3a 100644
--- a/lasso/saml-2.0/provider.c
+++ b/lasso/saml-2.0/provider.c
@@ -27,6 +27,17 @@
#include <lasso/saml-2.0/providerprivate.h>
#include <lasso/id-ff/providerprivate.h>
+const char *profile_names[] = {
+ "", /* No fedterm in SAML 2.0 */
+ "NameIDMappingService",
+ "", /* No rni in SAML 2.0 */
+ "SingleLogoutService",
+ "SingleSignOnService",
+ "ArtifactResolutionService",
+ "ManageNameIDService",
+ "AssertionIDRequestService",
+ NULL
+};
static void
load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provider)
@@ -35,8 +46,8 @@ load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provide
int i;
xmlNode *t;
GList *elements;
- char *name, *binding;
- xmlChar *value;
+ char *name, *binding, *response_name;
+ xmlChar *value, *response_value;
t = xmlnode->children;
while (t) {
@@ -91,6 +102,15 @@ load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provide
name = g_strdup_printf("%s %s", t->name, binding_s);
}
xmlFree(binding);
+
+ response_value = xmlGetProp(t, (xmlChar*)"ResponseLocation");
+ if (response_value) {
+ response_name = g_strdup_printf("%s ResponseLocation", name);
+ elements = g_hash_table_lookup(descriptor, response_name);
+ elements = g_list_append(elements, g_strdup((char*)response_value));
+ g_hash_table_insert(descriptor, response_name, elements);
+ xmlFree(response_value);
+ }
} else {
name = g_strdup((char*)t->name);
value = xmlNodeGetContent(t);
@@ -183,18 +203,7 @@ lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
LassoHttpMethod method_bindings[] = {
LASSO_HTTP_METHOD_SOAP, LASSO_HTTP_METHOD_REDIRECT, LASSO_HTTP_METHOD_POST
};
- const char *profiles[] = {
- "", /* No fedterm in SAML 2.0 */
- "NameIDMappingService",
- "", /* No rni in SAML 2.0 */
- "SingleLogoutService",
- "SingleSignOnService",
- "ArtifactResolutionService",
- "ManageNameIDService",
- "AssertionIDRequestService",
- NULL
- };
-
+
if (remote_provider->role == LASSO_PROVIDER_ROLE_SP)
provider->role = LASSO_PROVIDER_ROLE_IDP;
if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP)
@@ -204,7 +213,7 @@ lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
char *s;
GList *l1, *l2;
- s = g_strdup_printf("%s %s", profiles[protocol_type], possible_bindings[i]);
+ s = g_strdup_printf("%s %s", profile_names[protocol_type], possible_bindings[i]);
l1 = lasso_provider_get_metadata_list(provider, s);
l2 = lasso_provider_get_metadata_list(remote_provider, s);
if (l1 && l2) {
@@ -252,3 +261,45 @@ lasso_saml20_provider_get_assertion_consumer_service_url(LassoProvider *provider
return NULL;
}
+gboolean
+lasso_saml20_provider_accept_http_method(LassoProvider *provider, LassoProvider *remote_provider,
+ LassoMdProtocolType protocol_type, LassoHttpMethod http_method,
+ gboolean initiate_profile)
+{
+ LassoProviderRole initiating_role;
+ char *protocol_profile;
+ char *http_methods[] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "HTTP-Post",
+ "HTTP-Redirect",
+ "SOAP",
+ "HTTP-Artifact",
+ NULL
+ };
+
+
+ initiating_role = remote_provider->role;
+ if (remote_provider->role == LASSO_PROVIDER_ROLE_SP) {
+ provider->role = LASSO_PROVIDER_ROLE_IDP;
+ }
+ if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP) {
+ provider->role = LASSO_PROVIDER_ROLE_SP;
+ }
+ if (initiate_profile)
+ initiating_role = provider->role;
+
+ protocol_profile = g_strdup_printf("%s %s", profile_names[protocol_type],
+ http_methods[http_method+1]);
+
+ if (lasso_provider_get_metadata_list(provider, protocol_profile) &&
+ lasso_provider_get_metadata_list(remote_provider, protocol_profile)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
diff --git a/lasso/saml-2.0/providerprivate.h b/lasso/saml-2.0/providerprivate.h
index 7e47dbf4..9660dc7a 100644
--- a/lasso/saml-2.0/providerprivate.h
+++ b/lasso/saml-2.0/providerprivate.h
@@ -37,6 +37,10 @@ gboolean lasso_saml20_provider_load_metadata(LassoProvider *provider, xmlNode *r
LassoHttpMethod lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
LassoProvider *remote_provider, LassoMdProtocolType protocol_type);
+gboolean lasso_saml20_provider_accept_http_method(LassoProvider *provider,
+ LassoProvider *remote_provider, LassoMdProtocolType protocol_type,
+ LassoHttpMethod http_method, gboolean initiate_profile);
+
char* lasso_saml20_provider_build_artifact(LassoProvider *provider);
gchar* lasso_saml20_provider_get_assertion_consumer_service_url(LassoProvider *provider,
diff --git a/lasso/xml/private.h b/lasso/xml/private.h
index 2f54e733..e614d954 100644
--- a/lasso/xml/private.h
+++ b/lasso/xml/private.h
@@ -162,6 +162,10 @@ static inline void message(GLogLevelFlags level, const char *format, ...)
#define critical_error(rc) error_code(G_LOG_LEVEL_CRITICAL, rc)
+#define IF_SAML2(profile) \
+ if (lasso_provider_get_protocol_conformance(LASSO_PROVIDER(profile->server)) == \
+ LASSO_PROTOCOL_SAML_2_0)
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/xml/saml-2.0/Makefile.am b/lasso/xml/saml-2.0/Makefile.am
index b2761909..2b04dd6f 100644
--- a/lasso/xml/saml-2.0/Makefile.am
+++ b/lasso/xml/saml-2.0/Makefile.am
@@ -43,7 +43,9 @@ liblasso_xml_saml2_la_SOURCES = \
samlp2_idp_entry.c \
samlp2_idp_list.c \
samlp2_logout_request.c \
+ samlp2_logout_response.c \
samlp2_manage_name_id_request.c \
+ samlp2_manage_name_id_response.c \
samlp2_name_id_mapping_request.c \
samlp2_name_id_mapping_response.c \
samlp2_name_id_policy.c \
@@ -93,7 +95,9 @@ liblassoinclude_HEADERS = \
samlp2_idp_entry.h \
samlp2_idp_list.h \
samlp2_logout_request.h \
+ samlp2_logout_response.h \
samlp2_manage_name_id_request.h \
+ samlp2_manage_name_id_response.h \
samlp2_name_id_mapping_request.h \
samlp2_name_id_mapping_response.h \
samlp2_name_id_policy.h \
diff --git a/lasso/xml/saml-2.0/samlp2_artifact_resolve.c b/lasso/xml/saml-2.0/samlp2_artifact_resolve.c
index 522ed196..28295a0e 100644
--- a/lasso/xml/saml-2.0/samlp2_artifact_resolve.c
+++ b/lasso/xml/saml-2.0/samlp2_artifact_resolve.c
@@ -52,32 +52,6 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
-static gchar*
-build_query(LassoNode *node)
-{
- char *ret, *deflated_message;
-
- deflated_message = lasso_node_build_deflated_query(node);
- ret = g_strdup_printf("SAMLRequest=%s", deflated_message);
- /* XXX: must support RelayState (which profiles?) */
- g_free(deflated_message);
- return ret;
-}
-
-
-static gboolean
-init_from_query(LassoNode *node, char **query_fields)
-{
- gboolean rc;
- char *relay_state = NULL;
- rc = lasso_node_init_from_saml2_query_fields(node, query_fields, &relay_state);
- if (rc && relay_state != NULL) {
- /* XXX: support RelayState? */
- }
- return rc;
-}
-
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -94,8 +68,6 @@ class_init(LassoSamlp2ArtifactResolveClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
- nclass->build_query = build_query;
- nclass->init_from_query = init_from_query;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "ArtifactResolve");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
diff --git a/lasso/xml/saml-2.0/samlp2_logout_response.c b/lasso/xml/saml-2.0/samlp2_logout_response.c
new file mode 100644
index 00000000..12c775ec
--- /dev/null
+++ b/lasso/xml/saml-2.0/samlp2_logout_response.c
@@ -0,0 +1,129 @@
+/* $Id$
+ *
+ * Lasso - A free implementation of the Liberty Alliance specifications.
+ *
+ * Copyright (C) 2004, 2005 Entr'ouvert
+ * http://lasso.entrouvert.org
+ *
+ * Authors: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "samlp2_logout_response.h"
+
+/*
+ * Schema fragment (saml-schema-protocol-2.0.xsd):
+ *
+ * <element name="LogoutResponse" type="samlp:StatusResponseType"/>
+ */
+
+/*****************************************************************************/
+/* private methods */
+/*****************************************************************************/
+
+
+static struct XmlSnippet schema_snippets[] = {
+ {NULL, 0, 0}
+};
+
+static LassoNodeClass *parent_class = NULL;
+
+
+static gchar*
+build_query(LassoNode *node)
+{
+ char *ret, *deflated_message;
+
+ deflated_message = lasso_node_build_deflated_query(node);
+ ret = g_strdup_printf("SAMLResponse=%s", deflated_message);
+ /* XXX: must support RelayState (which profiles?) */
+ g_free(deflated_message);
+ return ret;
+}
+
+
+static gboolean
+init_from_query(LassoNode *node, char **query_fields)
+{
+ gboolean rc;
+ char *relay_state = NULL;
+ rc = lasso_node_init_from_saml2_query_fields(node, query_fields, &relay_state);
+ if (rc && relay_state != NULL) {
+ /* XXX: support RelayState? */
+ }
+ return rc;
+}
+
+
+/*****************************************************************************/
+/* instance and class init functions */
+/*****************************************************************************/
+
+static void
+instance_init(LassoSamlp2LogoutResponse *node)
+{
+}
+
+static void
+class_init(LassoSamlp2LogoutResponseClass *klass)
+{
+ LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+ nclass->build_query = build_query;
+ nclass->init_from_query = init_from_query;
+ nclass->node_data = g_new0(LassoNodeClassData, 1);
+ lasso_node_class_set_nodename(nclass, "LogoutResponse");
+ lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
+ lasso_node_class_add_snippets(nclass, schema_snippets);
+}
+
+GType
+lasso_samlp2_logout_response_get_type()
+{
+ static GType this_type = 0;
+
+ if (!this_type) {
+ static const GTypeInfo this_info = {
+ sizeof (LassoSamlp2LogoutResponseClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) class_init,
+ NULL,
+ NULL,
+ sizeof(LassoSamlp2LogoutResponse),
+ 0,
+ (GInstanceInitFunc) instance_init,
+ };
+
+ this_type = g_type_register_static(LASSO_TYPE_SAMLP2_STATUS_RESPONSE,
+ "LassoSamlp2LogoutResponse", &this_info, 0);
+ }
+ return this_type;
+}
+
+/**
+ * lasso_samlp2_logout_response_new:
+ *
+ * Creates a new #LassoSamlp2LogoutResponse object.
+ *
+ * Return value: a newly created #LassoSamlp2LogoutResponse object
+ **/
+LassoNode*
+lasso_samlp2_logout_response_new()
+{
+ return g_object_new(LASSO_TYPE_SAMLP2_LOGOUT_RESPONSE, NULL);
+}
diff --git a/lasso/xml/saml-2.0/samlp2_manage_name_id_response.c b/lasso/xml/saml-2.0/samlp2_manage_name_id_response.c
new file mode 100644
index 00000000..59d2d0e3
--- /dev/null
+++ b/lasso/xml/saml-2.0/samlp2_manage_name_id_response.c
@@ -0,0 +1,129 @@
+/* $Id$
+ *
+ * Lasso - A free implementation of the Liberty Alliance specifications.
+ *
+ * Copyright (C) 2004, 2005 Entr'ouvert
+ * http://lasso.entrouvert.org
+ *
+ * Authors: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "samlp2_manage_name_id_response.h"
+
+/*
+ * Schema fragment (saml-schema-protocol-2.0.xsd):
+ *
+ * <element name="ManageNameIDResponse" type="samlp:StatusResponseType"/>
+ */
+
+/*****************************************************************************/
+/* private methods */
+/*****************************************************************************/
+
+
+static struct XmlSnippet schema_snippets[] = {
+ {NULL, 0, 0}
+};
+
+static LassoNodeClass *parent_class = NULL;
+
+
+static gchar*
+build_query(LassoNode *node)
+{
+ char *ret, *deflated_message;
+
+ deflated_message = lasso_node_build_deflated_query(node);
+ ret = g_strdup_printf("SAMLResponse=%s", deflated_message);
+ /* XXX: must support RelayState (which profiles?) */
+ g_free(deflated_message);
+ return ret;
+}
+
+
+static gboolean
+init_from_query(LassoNode *node, char **query_fields)
+{
+ gboolean rc;
+ char *relay_state = NULL;
+ rc = lasso_node_init_from_saml2_query_fields(node, query_fields, &relay_state);
+ if (rc && relay_state != NULL) {
+ /* XXX: support RelayState? */
+ }
+ return rc;
+}
+
+
+/*****************************************************************************/
+/* instance and class init functions */
+/*****************************************************************************/
+
+static void
+instance_init(LassoSamlp2ManageNameIDResponse *node)
+{
+}
+
+static void
+class_init(LassoSamlp2ManageNameIDResponseClass *klass)
+{
+ LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+ nclass->build_query = build_query;
+ nclass->init_from_query = init_from_query;
+ nclass->node_data = g_new0(LassoNodeClassData, 1);
+ lasso_node_class_set_nodename(nclass, "ManageNameIDResponse");
+ lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
+ lasso_node_class_add_snippets(nclass, schema_snippets);
+}
+
+GType
+lasso_samlp2_manage_name_id_response_get_type()
+{
+ static GType this_type = 0;
+
+ if (!this_type) {
+ static const GTypeInfo this_info = {
+ sizeof (LassoSamlp2ManageNameIDResponseClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) class_init,
+ NULL,
+ NULL,
+ sizeof(LassoSamlp2ManageNameIDResponse),
+ 0,
+ (GInstanceInitFunc) instance_init,
+ };
+
+ this_type = g_type_register_static(LASSO_TYPE_SAMLP2_STATUS_RESPONSE,
+ "LassoSamlp2ManageNameIDResponse", &this_info, 0);
+ }
+ return this_type;
+}
+
+/**
+ * lasso_samlp2_manage_name_id_response_new:
+ *
+ * Creates a new #LassoSamlp2ManageNameIDResponse object.
+ *
+ * Return value: a newly created #LassoSamlp2ManageNameIDResponse object
+ **/
+LassoNode*
+lasso_samlp2_manage_name_id_response_new()
+{
+ return g_object_new(LASSO_TYPE_SAMLP2_MANAGE_NAME_ID_RESPONSE, NULL);
+}
diff --git a/lasso/xml/saml-2.0/samlp2_name_id_mapping_response.c b/lasso/xml/saml-2.0/samlp2_name_id_mapping_response.c
index bc497df6..8ed1966a 100644
--- a/lasso/xml/saml-2.0/samlp2_name_id_mapping_response.c
+++ b/lasso/xml/saml-2.0/samlp2_name_id_mapping_response.c
@@ -56,6 +56,32 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
+static gchar*
+build_query(LassoNode *node)
+{
+ char *ret, *deflated_message;
+
+ deflated_message = lasso_node_build_deflated_query(node);
+ ret = g_strdup_printf("SAMLResponse=%s", deflated_message);
+ /* XXX: must support RelayState (which profiles?) */
+ g_free(deflated_message);
+ return ret;
+}
+
+
+static gboolean
+init_from_query(LassoNode *node, char **query_fields)
+{
+ gboolean rc;
+ char *relay_state = NULL;
+ rc = lasso_node_init_from_saml2_query_fields(node, query_fields, &relay_state);
+ if (rc && relay_state != NULL) {
+ /* XXX: support RelayState? */
+ }
+ return rc;
+}
+
+
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -73,6 +99,8 @@ class_init(LassoSamlp2NameIDMappingResponseClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
+ nclass->build_query = build_query;
+ nclass->init_from_query = init_from_query;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "NameIDMappingResponse");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
diff --git a/lasso/xml/saml-2.0/samlp2_request_abstract.c b/lasso/xml/saml-2.0/samlp2_request_abstract.c
index 6957e736..cfa7a1f7 100644
--- a/lasso/xml/saml-2.0/samlp2_request_abstract.c
+++ b/lasso/xml/saml-2.0/samlp2_request_abstract.c
@@ -68,6 +68,17 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, Consent) },
{ "Signature", SNIPPET_SIGNATURE,
G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, ID) },
+
+ /* hidden fields; used in lasso dumps */
+ { "SignType", SNIPPET_ATTRIBUTE | SNIPPET_INTEGER | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, sign_type) },
+ { "SignMethod", SNIPPET_ATTRIBUTE | SNIPPET_INTEGER | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, sign_method) },
+ { "PrivateKeyFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, private_key_file) },
+ { "CertificateFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, certificate_file) },
+
{NULL, 0, 0}
};
diff --git a/lasso/xml/saml-2.0/samlp2_response.c b/lasso/xml/saml-2.0/samlp2_response.c
index b2bf27f8..e32616f7 100644
--- a/lasso/xml/saml-2.0/samlp2_response.c
+++ b/lasso/xml/saml-2.0/samlp2_response.c
@@ -55,6 +55,32 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
+static gchar*
+build_query(LassoNode *node)
+{
+ char *ret, *deflated_message;
+
+ deflated_message = lasso_node_build_deflated_query(node);
+ ret = g_strdup_printf("SAMLResponse=%s", deflated_message);
+ /* XXX: must support RelayState (which profiles?) */
+ g_free(deflated_message);
+ return ret;
+}
+
+
+static gboolean
+init_from_query(LassoNode *node, char **query_fields)
+{
+ gboolean rc;
+ char *relay_state = NULL;
+ rc = lasso_node_init_from_saml2_query_fields(node, query_fields, &relay_state);
+ if (rc && relay_state != NULL) {
+ /* XXX: support RelayState? */
+ }
+ return rc;
+}
+
+
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -72,6 +98,8 @@ class_init(LassoSamlp2ResponseClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
+ nclass->build_query = build_query;
+ nclass->init_from_query = init_from_query;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "Response");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
diff --git a/lasso/xml/saml-2.0/samlp2_status_response.c b/lasso/xml/saml-2.0/samlp2_status_response.c
index 2fa79fb3..5cf70a1d 100644
--- a/lasso/xml/saml-2.0/samlp2_status_response.c
+++ b/lasso/xml/saml-2.0/samlp2_status_response.c
@@ -74,12 +74,49 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoSamlp2StatusResponse, Consent) },
{ "Signature", SNIPPET_SIGNATURE,
G_STRUCT_OFFSET(LassoSamlp2StatusResponse, ID) },
+
+ /* hidden fields; used in lasso dumps */
+ { "SignType", SNIPPET_ATTRIBUTE | SNIPPET_INTEGER | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2StatusResponse, sign_type) },
+ { "SignMethod", SNIPPET_ATTRIBUTE | SNIPPET_INTEGER | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2StatusResponse, sign_method) },
+ { "PrivateKeyFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2StatusResponse, private_key_file) },
+ { "CertificateFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2StatusResponse, certificate_file) },
+
{NULL, 0, 0}
};
static LassoNodeClass *parent_class = NULL;
+static gchar*
+build_query(LassoNode *node)
+{
+ char *ret, *deflated_message;
+
+ deflated_message = lasso_node_build_deflated_query(node);
+ ret = g_strdup_printf("SAMLResponse=%s", deflated_message);
+ /* XXX: must support RelayState (which profiles?) */
+ g_free(deflated_message);
+ return ret;
+}
+
+
+static gboolean
+init_from_query(LassoNode *node, char **query_fields)
+{
+ gboolean rc;
+ char *relay_state = NULL;
+ rc = lasso_node_init_from_saml2_query_fields(node, query_fields, &relay_state);
+ if (rc && relay_state != NULL) {
+ /* XXX: support RelayState? */
+ }
+ return rc;
+}
+
+
static xmlNode*
get_xmlNode(LassoNode *node, gboolean lasso_dump)
@@ -125,6 +162,8 @@ class_init(LassoSamlp2StatusResponseClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
+ nclass->build_query = build_query;
+ nclass->init_from_query = init_from_query;
nclass->get_xmlNode = get_xmlNode;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "StatusResponse");
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index ff07cc2f..6ae2a7e5 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -1121,6 +1121,7 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, xmlNode *xmlnode,
case SNIPPET_LASSO_DUMP:
case SNIPPET_OPTIONAL:
case SNIPPET_OPTIONAL_NEG:
+ case SNIPPET_ANY:
g_assert_not_reached();
}
if (snippet->type & SNIPPET_INTEGER)