summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-12 15:39:48 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-12 15:39:48 +0000
commit2ff13e5414a25e85a79417413e6bca36b44f4153 (patch)
tree49fd794f944713e6f4468bd7ab517b14ac434f40
parent0988cc2ec8650ee7bd30b4869a9b0afec704c89f (diff)
downloadlasso-2ff13e5414a25e85a79417413e6bca36b44f4153.tar.gz
lasso-2ff13e5414a25e85a79417413e6bca36b44f4153.tar.xz
lasso-2ff13e5414a25e85a79417413e6bca36b44f4153.zip
SAML 2.0: overhaul for ubuquitous binding support, still need work for HTTP-Artefact
-rw-r--r--lasso/errors.c10
-rw-r--r--lasso/errors.h17
-rw-r--r--lasso/id-ff/login.c2
-rw-r--r--lasso/id-ff/logout.c9
-rw-r--r--lasso/id-ff/profile.c83
-rw-r--r--lasso/id-ff/provider.c13
-rw-r--r--lasso/id-ff/provider.h2
-rw-r--r--lasso/saml-2.0/assertion_query.c66
-rw-r--r--lasso/saml-2.0/ecp.c1
-rw-r--r--lasso/saml-2.0/login.c650
-rw-r--r--lasso/saml-2.0/loginprivate.h2
-rw-r--r--lasso/saml-2.0/logout.c334
-rw-r--r--lasso/saml-2.0/logoutprivate.h2
-rw-r--r--lasso/saml-2.0/name_id_management.c38
-rw-r--r--lasso/saml-2.0/profile.c702
-rw-r--r--lasso/saml-2.0/profileprivate.h25
-rw-r--r--lasso/saml-2.0/provider.c2
-rw-r--r--lasso/saml-2.0/saml2_helper.c4
-rw-r--r--lasso/saml-2.0/saml2_helper.h11
-rw-r--r--lasso/xml/saml-2.0/samlp2_request_abstract.c4
-rw-r--r--lasso/xml/saml-2.0/samlp2_status_response.c4
21 files changed, 954 insertions, 1027 deletions
diff --git a/lasso/errors.c b/lasso/errors.c
index 987cd469..8b324c08 100644
--- a/lasso/errors.c
+++ b/lasso/errors.c
@@ -117,6 +117,8 @@ lasso_strerror(int error_code)
return "SAML signature must contain only one reference";
case LASSO_PROFILE_ERROR_MISSING_SERVICE_TYPE:
return "Missing service type";
+ case LASSO_PROFILE_ERROR_UNSUPPORTED_BINDING:
+ return "The responder reported that he does not support this binding";
case LASSO_PROFILE_ERROR_CANNOT_FIND_A_PROVIDER:
return "Profile was called without a specific provider and we cannot find one.";
case LASSO_DS_ERROR_INVALID_REFERENCE_FOR_SAML:
@@ -153,6 +155,8 @@ lasso_strerror(int error_code)
return "Invalid signature.";
case LASSO_WSF_PROFILE_ERROR_SERVER_INTERACTION_REQUIRED_FOR_DATA:
return "redirect requests.";
+ case LASSO_IDWSF2_DST_ERROR_PARTIAL_FAILURE:
+ return "Server responded with a partial failure status code.";
case LASSO_DS_ERROR_DECRYPTION_FAILED:
return "Decryption of an encrypted node failed";
case LASSO_IDWSF2_DISCOVERY_ERROR_NO_RESULTS:
@@ -181,6 +185,8 @@ lasso_strerror(int error_code)
return "Failed to create session from dump";
case LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED:
return "Error building request QUERY url";
+ case LASSO_DS_ERROR_ENCRYPTION_FAILED:
+ return "Creation of an encrypted node failed";
case LASSO_DST_ERROR_MISSING_SERVICE_DATA:
return "Missing service data";
case LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED:
@@ -205,6 +211,8 @@ lasso_strerror(int error_code)
return "A response contained an unknown status code.";
case LASSO_PROFILE_ERROR_INVALID_QUERY:
return "Invalid URL query";
+ case LASSO_IDWSF2_DST_ERROR_UNKNOWN_STATUS_CODE:
+ return "Server response with an unknown status code.";
case LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED:
return "LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED";
case LASSO_PROFILE_ERROR_MISSING_RESPONSE:
@@ -243,6 +251,8 @@ lasso_strerror(int error_code)
return "The error return location should be either NULL or contains a NULL error.";
case LASSO_SOAP_ERROR_MISSING_BODY:
return "Missing SOAP body";
+ case LASSO_IDWSF2_DST_ERROR_ITEM_NOT_FOUND:
+ return "The item_id was not found in the current query request.";
case LASSO_XML_ERROR_INVALID_FILE:
return "Invalid XML file";
case LASSO_WSF_PROFILE_ERROR_MISSING_ENDPOINT:
diff --git a/lasso/errors.h b/lasso/errors.h
index ceadd2bd..059667a3 100644
--- a/lasso/errors.h
+++ b/lasso/errors.h
@@ -198,7 +198,14 @@
*
* Decryption of an encrypted node failed
*/
-#define LASSO_DS_ERROR_DECRYPTION_FAILED -118
+#define LASSO_DS_ERROR_DECRYPTION_FAILED 118
+/**
+ * LASSO_DS_ERROR_ENCRYPTION_FAILED:
+ *
+ * Creation of an encrypted node failed
+ */
+#define LASSO_DS_ERROR_ENCRYPTION_FAILED -119
+
/* Server */
/**
@@ -506,7 +513,6 @@
* Received response does not refer to the request sent
*/
#define LASSO_PROFILE_ERROR_RESPONSE_DOES_NOT_MATCH_REQUEST -442
-
/**
* LASSO_PROFILE_ERROR_INVALID_REQUEST:
*
@@ -520,6 +526,13 @@
* Received request is not of the expected type.
*/
#define LASSO_PROFILE_ERROR_INVALID_RESPONSE 444
+/**
+ * LASSO_PROFILE_ERROR_UNSUPPPORTED_BINDING
+ *
+ * The responder reported that he does not support this binding
+ */
+#define LASSO_PROFILE_ERROR_UNSUPPORTED_BINDING 445
+
/* functions/methods parameters checking */
/**
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 7d2c0ef8..52d034e4 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -929,7 +929,7 @@ lasso_login_build_authn_request_msg(LassoLogin *login)
}
IF_SAML2(profile) {
- return lasso_saml20_login_build_authn_request_msg(login, remote_provider);
+ return lasso_saml20_login_build_authn_request_msg(login);
}
protocolProfile = LASSO_LIB_AUTHN_REQUEST(profile->request)->ProtocolProfile;
diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c
index 507a70d3..0d934208 100644
--- a/lasso/id-ff/logout.c
+++ b/lasso/id-ff/logout.c
@@ -88,6 +88,10 @@ lasso_logout_build_request_msg(LassoLogout *logout)
profile = LASSO_PROFILE(logout);
lasso_profile_clean_msg_info(profile);
+ IF_SAML2(profile) {
+ return lasso_saml20_logout_build_request_msg(logout);
+ }
+
if (profile->remote_providerID == NULL) {
/* this means lasso_logout_init_request was not called before */
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
@@ -99,10 +103,6 @@ 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 */
@@ -1100,6 +1100,7 @@ finalize(GObject *object)
static void
instance_init(LassoLogout *logout)
{
+ logout->initial_http_request_method = LASSO_HTTP_METHOD_NONE;
logout->private_data = g_new0(LassoLogoutPrivate, 1);
logout->private_data->dispose_has_run = FALSE;
}
diff --git a/lasso/id-ff/profile.c b/lasso/id-ff/profile.c
index 3998ff1c..f378027d 100644
--- a/lasso/id-ff/profile.c
+++ b/lasso/id-ff/profile.c
@@ -43,6 +43,8 @@
#include "./sessionprivate.h"
#include "../saml-2.0/profileprivate.h"
+#include "../xml/saml-2.0/saml2_name_id.h"
+#include "../xml/saml-2.0/saml2_assertion.h"
#include "../utils.h"
#include "../debug.h"
@@ -50,6 +52,38 @@
/* public functions */
/*****************************************************************************/
+static LassoNode*
+_lasso_saml_assertion_get_name_id(LassoSamlAssertion *assertion)
+{
+ LassoSamlAuthenticationStatement *authn_statement;
+ LassoSamlSubject *subject;
+
+ goto_cleanup_if_fail(LASSO_IS_SAML_ASSERTION(assertion));
+ authn_statement = assertion->AuthenticationStatement;
+ goto_cleanup_if_fail(LASSO_IS_SAML_AUTHENTICATION_STATEMENT(authn_statement));
+ subject = authn_statement->parent.Subject;
+ goto_cleanup_if_fail(LASSO_IS_SAML_SUBJECT(subject));
+ if (LASSO_IS_SAML_NAME_IDENTIFIER(subject->NameIdentifier))
+ return (LassoNode*)subject->NameIdentifier;
+cleanup:
+ return NULL;
+}
+
+static LassoNode*
+_lasso_saml2_assertion_get_name_id(LassoSaml2Assertion *assertion)
+{
+ LassoSaml2Subject *subject;
+
+ goto_cleanup_if_fail(LASSO_SAML2_ASSERTION(assertion));
+ subject = assertion->Subject;
+ goto_cleanup_if_fail(LASSO_SAML2_SUBJECT(subject));
+ if (LASSO_IS_SAML2_NAME_ID(subject->NameID))
+ return (LassoNode*)subject->NameID;
+
+cleanup:
+ return NULL;
+}
+
/**
* lasso_profile_get_nameIdentifier:
* @profile: a #LassoProfile
@@ -69,29 +103,48 @@ lasso_profile_get_nameIdentifier(LassoProfile *profile)
char *name_id_sp_name_qualifier;
g_return_val_if_fail(LASSO_IS_PROFILE(profile), NULL);
-
+
g_return_val_if_fail(LASSO_IS_SERVER(profile->server), NULL);
g_return_val_if_fail(LASSO_IS_IDENTITY(profile->identity), NULL);
- g_return_val_if_fail(profile->remote_providerID != NULL, NULL);
- remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
- if (remote_provider == NULL)
+ if (profile->remote_providerID == NULL)
return NULL;
- name_id_sp_name_qualifier = lasso_provider_get_sp_name_qualifier(remote_provider);
- if (name_id_sp_name_qualifier == NULL)
- return NULL;
+ if (LASSO_IS_IDENTITY(profile->identity)) {
+ remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
+ if (remote_provider == NULL)
+ goto use_session;
- federation = g_hash_table_lookup(
- profile->identity->federations,
- name_id_sp_name_qualifier);
- if (federation == NULL)
- return NULL;
+ name_id_sp_name_qualifier = lasso_provider_get_sp_name_qualifier(remote_provider);
+ if (name_id_sp_name_qualifier == NULL)
+ goto use_session;
- if (federation->remote_nameIdentifier)
- return federation->remote_nameIdentifier;
+ federation = g_hash_table_lookup(
+ profile->identity->federations,
+ name_id_sp_name_qualifier);
+ if (federation == NULL)
+ goto use_session;
- return federation->local_nameIdentifier;
+ if (federation->remote_nameIdentifier)
+ return federation->remote_nameIdentifier;
+ return federation->local_nameIdentifier;
+ }
+use_session:
+ /* For transient federations, so we must look at assertions no federation object exists */
+ if (LASSO_IS_SESSION(profile->session)) {
+ LassoNode *assertion, *name_id;
+
+ assertion = lasso_session_get_assertion(profile->session,
+ profile->remote_providerID);
+
+ name_id = _lasso_saml_assertion_get_name_id((LassoSamlAssertion*)assertion);
+ if (name_id)
+ return name_id;
+ name_id = _lasso_saml2_assertion_get_name_id((LassoSaml2Assertion*)assertion);
+ if (name_id)
+ return name_id;
+ }
+ return NULL;
}
/**
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index 0fd8de69..4cc4f248 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -1271,6 +1271,19 @@ lasso_provider_set_encryption_mode(LassoProvider *provider, LassoEncryptionMode
}
/**
+ * lasso_provider_get_encryption_mode:
+ * @provider: a #LassoProvider object
+ *
+ * Return the current encryption mode.
+ */
+LassoEncryptionMode
+lasso_provider_get_encryption_mode(LassoProvider *provider) {
+ if (! LASSO_IS_PROVIDER(provider) || ! provider->private_data)
+ return LASSO_ENCRYPTION_MODE_NONE;
+ return provider->private_data->encryption_mode;
+}
+
+/**
* lasso_provider_set_encryption_sym_key_type:
* @provider: provider to set encryption for
* @encryption_sym_key_type: enum type for generated symetric key
diff --git a/lasso/id-ff/provider.h b/lasso/id-ff/provider.h
index c2a74107..a787a525 100644
--- a/lasso/id-ff/provider.h
+++ b/lasso/id-ff/provider.h
@@ -203,6 +203,8 @@ LASSO_EXPORT LassoProtocolConformance lasso_provider_get_protocol_conformance(
LASSO_EXPORT void lasso_provider_set_encryption_mode(LassoProvider *provider,
LassoEncryptionMode encryption_mode);
+LASSO_EXPORT LassoEncryptionMode lasso_provider_get_encryption_mode(LassoProvider *provider);
+
LASSO_EXPORT void lasso_provider_set_encryption_sym_key_type(LassoProvider *provider,
LassoEncryptionSymKeyType encryption_sym_key_type);
diff --git a/lasso/saml-2.0/assertion_query.c b/lasso/saml-2.0/assertion_query.c
index 1d083491..9e9c7254 100644
--- a/lasso/saml-2.0/assertion_query.c
+++ b/lasso/saml-2.0/assertion_query.c
@@ -379,70 +379,18 @@ lasso_assertion_query_process_response_msg(
gchar *response_msg)
{
LassoProfile *profile;
- LassoHttpMethod response_method;
- LassoProvider *remote_provider;
LassoSamlp2StatusResponse *response;
- LassoMessageFormat format;
- char *status_code_value;
int rc;
- g_return_val_if_fail(LASSO_IS_ASSERTION_QUERY(assertion_query),
- LASSO_PARAM_ERROR_INVALID_VALUE);
- g_return_val_if_fail(response_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
-
- profile = LASSO_PROFILE(assertion_query);
-
- if (LASSO_IS_SAMLP2_MANAGE_NAME_ID_RESPONSE(profile->response) == TRUE) {
- lasso_node_destroy(profile->response);
- profile->response = NULL;
- }
-
- profile->response = lasso_samlp2_response_new();
- format = lasso_node_init_from_message(LASSO_NODE(profile->response), response_msg);
-
- switch (format) {
- case LASSO_MESSAGE_FORMAT_SOAP:
- response_method = LASSO_HTTP_METHOD_SOAP;
- break;
- case LASSO_MESSAGE_FORMAT_QUERY:
- response_method = LASSO_HTTP_METHOD_REDIRECT;
- break;
- default:
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
-
- profile->remote_providerID = g_strdup(
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->Issuer->content);
-
- /* 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);
- }
-
- /* verify signature */
- rc = lasso_provider_verify_signature(remote_provider, response_msg, "ID", format);
- if (rc == LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
- /* XXX: is signature mandatory ? */
- message(G_LOG_LEVEL_WARNING, "No signature on response");
- rc = 0;
- }
-
- response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
-
- if (response->Status == NULL || response->Status->StatusCode == NULL
- || response->Status->StatusCode->Value == NULL) {
- message(G_LOG_LEVEL_CRITICAL, "No Status in Response !");
- return LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
- }
- status_code_value = response->Status->StatusCode->Value;
+ lasso_bad_param(ASSERTION_QUERY, assertion_query);
+ profile = &assertion_query->parent;
+ response = (LassoSamlp2StatusResponse*)lasso_samlp2_response_new();
- if (strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_SUCCESS) != 0) {
- message(G_LOG_LEVEL_CRITICAL, "Status code is not success: %s", status_code_value);
- return LASSO_PROFILE_ERROR_STATUS_NOT_SUCCESS;
- }
+ rc = lasso_saml20_profile_process_any_response(profile, response, NULL, response_msg);
- return 0;
+/* cleanup: */
+ lasso_release_gobject(response);
+ return rc;
}
diff --git a/lasso/saml-2.0/ecp.c b/lasso/saml-2.0/ecp.c
index 48b0ae77..5d08d7c8 100644
--- a/lasso/saml-2.0/ecp.c
+++ b/lasso/saml-2.0/ecp.c
@@ -162,6 +162,7 @@ lasso_ecp_process_authn_request_msg(LassoEcp *ecp, const char *authn_request_msg
if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
xmlnode = xpathObj->nodesetval->nodeTab[0];
xmlUnlinkNode(xmlnode);
+ xmlFreeNode(xmlnode);
}
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 95c4a3bc..ccce04e9 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -26,10 +26,10 @@
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
-#include "providerprivate.h"
-#include "loginprivate.h"
-#include "profileprivate.h"
-#include "federationprivate.h"
+#include "./providerprivate.h"
+#include "./loginprivate.h"
+#include "./profileprivate.h"
+#include "./federationprivate.h"
#include "./saml2_helper.h"
#include "../id-ff/providerprivate.h"
@@ -60,6 +60,8 @@ static gint lasso_saml20_login_process_response_status_and_assertion(LassoLogin
static char* lasso_saml20_login_get_assertion_consumer_service_url(LassoLogin *login,
LassoProvider *remote_provider);
+/* No need to check type of arguments, it has been done in lasso_login_* methods */
+
gint
lasso_saml20_login_init_authn_request(LassoLogin *login, LassoHttpMethod http_method)
{
@@ -69,7 +71,6 @@ lasso_saml20_login_init_authn_request(LassoLogin *login, LassoHttpMethod http_me
gchar *default_name_id_format = NULL;
int rc = 0;
- lasso_bad_param(LOGIN, login);
profile = &login->parent;
lasso_extract_node_or_fail(server, lasso_profile_get_server(profile), SERVER,
LASSO_PROFILE_ERROR_MISSING_SERVER);
@@ -112,104 +113,98 @@ lasso_saml20_login_init_authn_request(LassoLogin *login, LassoHttpMethod http_me
lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(request)->NameIDPolicy->SPNameQualifier,
request->Issuer->content);
- if (http_method != LASSO_HTTP_METHOD_REDIRECT) {
- request->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
- if (profile->server->certificate) {
- request->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
- } else {
- request->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
- }
- }
-
cleanup:
return rc;
}
+static gboolean
+_lasso_login_must_sign_non_authn_request(LassoLogin *profile)
+{
+ switch (lasso_profile_get_signature_hint(&profile->parent)) {
+ case LASSO_PROFILE_SIGNATURE_HINT_MAYBE:
+ return lasso_flag_add_signature;
+ case LASSO_PROFILE_SIGNATURE_HINT_FORCE:
+ return TRUE;
+ case LASSO_PROFILE_SIGNATURE_HINT_FORBID:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
-gint
-lasso_saml20_login_build_authn_request_msg(LassoLogin *login, LassoProvider *remote_provider)
+static gboolean
+_lasso_login_must_sign(LassoProfile *profile)
{
- char *url;
char *md_authnRequestsSigned;
- gboolean must_sign;
- LassoProfile *profile = LASSO_PROFILE(login);
+ gboolean ret;
+
+ switch (lasso_profile_get_signature_hint(profile)) {
+ case LASSO_PROFILE_SIGNATURE_HINT_MAYBE:
+ md_authnRequestsSigned = lasso_provider_get_metadata_one(
+ LASSO_PROVIDER(profile->server), "AuthnRequestsSigned");
+ /* default is to sign ! */
+ ret = ! md_authnRequestsSigned || g_strcmp0(md_authnRequestsSigned, "false") != 0;
+ lasso_release_string(md_authnRequestsSigned);
+ return ret;
+ case LASSO_PROFILE_SIGNATURE_HINT_FORCE:
+ return TRUE;
+ case LASSO_PROFILE_SIGNATURE_HINT_FORBID:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+gint
+lasso_saml20_login_build_authn_request_msg(LassoLogin *login)
+{
+ char *url = NULL;
+ gboolean must_sign = TRUE;
+ LassoProfile *profile;
+ LassoSamlp2AuthnRequest *authn_request;
+ int rc = 0;
+ LassoHttpMethod http_method;
- md_authnRequestsSigned = lasso_provider_get_metadata_one(
- LASSO_PROVIDER(profile->server), "AuthnRequestsSigned");
- must_sign = (md_authnRequestsSigned && strcmp(md_authnRequestsSigned, "true") == 0);
- g_free(md_authnRequestsSigned);
+ profile = &login->parent;
+ http_method = login->http_method;
- if (! lasso_flag_sign_messages && must_sign) {
- message(G_LOG_LEVEL_WARNING, "AuthnRequest message should normally be signed but \"no-sign-messages\" option is activated");
- }
+ lasso_extract_node_or_fail(authn_request, profile->request, SAMLP2_AUTHN_REQUEST,
+ LASSO_PROFILE_ERROR_INVALID_REQUEST);
- if (login->http_method == LASSO_HTTP_METHOD_REDIRECT) {
- return lasso_saml20_build_http_redirect_query_simple(profile, profile->request,
- must_sign, "SingleSignOnService", FALSE);
- } else {
- /* POST, SOAP and Artifact-GET|POST */
- if (must_sign && lasso_flag_sign_messages) {
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file,
- profile->server->private_key);
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file,
- profile->server->certificate);
- }
+ /* default is to sign ! */
+ must_sign = _lasso_login_must_sign(profile);
- if (login->http_method == LASSO_HTTP_METHOD_POST) {
- lasso_assign_new_string(profile->msg_url,
- lasso_provider_get_metadata_one(remote_provider,
- "SingleSignOnService HTTP-POST"));
- lasso_assign_new_string(profile->msg_body,
- lasso_node_export_to_base64(profile->request));
- } else if (login->http_method == LASSO_HTTP_METHOD_SOAP) {
- const char *issuer;
- const char *responseConsumerURL;
-
- issuer = LASSO_PROVIDER(LASSO_PROFILE(login)->server)->ProviderID;
- responseConsumerURL = \
- lasso_saml20_login_get_assertion_consumer_service_url(
- login, LASSO_PROVIDER(profile->server));
- lasso_release_string(profile->msg_url);
- lasso_assign_new_string(profile->msg_body,
- lasso_node_export_to_paos_request(profile->request,
- issuer, responseConsumerURL,
- profile->msg_relayState));
- } else {
- /* artifact method */
- char *artifact = lasso_saml20_profile_generate_artifact(profile, 0);
- url = lasso_provider_get_metadata_one(
- remote_provider, "SingleSignOnService HTTP-Artifact");
- if (login->http_method == LASSO_HTTP_METHOD_ARTIFACT_GET) {
- gchar *query;
-
- if (profile->msg_relayState) {
- query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, "RelayState",
- profile->msg_relayState, NULL);
- } else {
- query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, NULL);
- }
- lasso_assign_new_string(profile->msg_url,
- lasso_concat_url_query(url, query));
- lasso_release_string(query);
- lasso_release_string(url);
- } else {
- /* TODO: ARTIFACT POST */
- }
- }
+ if (! must_sign) {
+ lasso_node_remove_signature(profile->request);
}
- return 0;
+ /* support old way of doing PAOS */
+ if (login->http_method == LASSO_HTTP_METHOD_SOAP
+ && g_strcmp0(authn_request->ProtocolBinding,
+ LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
+ login->http_method = LASSO_HTTP_METHOD_PAOS;
+ /* PAOS is special, the url passed to build_request is the AssertionConsumerServiceURL of
+ * this SP, not the destination. */
+ url = lasso_saml20_login_get_assertion_consumer_service_url(login,
+ LASSO_PROVIDER(profile->server));
+ }
+
+ lasso_check_good_rc(lasso_saml20_profile_build_request_msg(profile, "SingleSignOnService",
+ login->http_method, url));
+
+cleanup:
+ return rc;
}
int
lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *authn_request_msg)
{
LassoNode *request;
- LassoMessageFormat format;
LassoProfile *profile = LASSO_PROFILE(login);
LassoSamlp2StatusResponse *response;
LassoSamlp2AuthnRequest *authn_request;
gchar *protocol_binding;
+ int rc = 0;
if (authn_request_msg == NULL) {
if (profile->request == NULL) {
@@ -220,23 +215,9 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
request = profile->request;
} else {
request = lasso_samlp2_authn_request_new();
- format = lasso_node_init_from_message(request, authn_request_msg);
- if (format == LASSO_MESSAGE_FORMAT_UNKNOWN ||
- format == LASSO_MESSAGE_FORMAT_ERROR) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
- if (format == LASSO_MESSAGE_FORMAT_QUERY) {
- lasso_assign_new_string(profile->msg_relayState,
- lasso_get_relaystate_from_query(authn_request_msg));
- }
+ lasso_check_good_rc(lasso_saml20_profile_process_any_request(profile, request, authn_request_msg));
}
-
authn_request = LASSO_SAMLP2_AUTHN_REQUEST(request);
-
- lasso_assign_new_gobject(profile->request, request);
- lasso_assign_string(profile->remote_providerID,
- LASSO_SAMLP2_REQUEST_ABSTRACT(request)->Issuer->content);
-
protocol_binding = authn_request->ProtocolBinding;
if (protocol_binding == NULL) {
/* protocol binding not set; so it will look into
@@ -259,46 +240,48 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
if (binding == NULL) {
if (service_index == -1)
return LASSO_LOGIN_ERROR_NO_DEFAULT_ENDPOINT;
- } else if (strcmp(binding, "HTTP-Artifact") == 0) {
+ } else if (g_strcmp0(binding, "HTTP-Artifact") == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART;
- } else if (strcmp(binding, "HTTP-POST") == 0) {
+ } else if (g_strcmp0(binding, "HTTP-POST") == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST;
- } else if (strcmp(binding, "HTTP-Redirect") == 0) {
+ } else if (g_strcmp0(binding, "HTTP-Redirect") == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT;
- } else if (strcmp(binding, "SOAP") == 0) {
+ } else if (g_strcmp0(binding, "SOAP") == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP;
- } else if (strcmp(binding, "PAOS") == 0) {
+ } else if (g_strcmp0(binding, "PAOS") == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP;
}
lasso_release_string(binding);
- } else if (strcmp(protocol_binding, LASSO_SAML2_METADATA_BINDING_ARTIFACT) == 0) {
+ } else if (g_strcmp0(protocol_binding, LASSO_SAML2_METADATA_BINDING_ARTIFACT) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART;
- } else if (strcmp(protocol_binding, LASSO_SAML2_METADATA_BINDING_POST) == 0) {
+ } else if (g_strcmp0(protocol_binding, LASSO_SAML2_METADATA_BINDING_POST) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST;
- } else if (strcmp(protocol_binding, LASSO_SAML2_METADATA_BINDING_SOAP) == 0) {
+ } else if (g_strcmp0(protocol_binding, LASSO_SAML2_METADATA_BINDING_SOAP) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP;
- } else if (strcmp(protocol_binding, LASSO_SAML2_METADATA_BINDING_REDIRECT) == 0) {
+ } else if (g_strcmp0(protocol_binding, LASSO_SAML2_METADATA_BINDING_REDIRECT) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT;
- } else if (strcmp(protocol_binding, LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
+ } else if (g_strcmp0(protocol_binding, LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP;
} else {
message(G_LOG_LEVEL_CRITICAL,
"unhandled protocol binding: %s", protocol_binding);
}
- /* XXX: checks authn request signature */
- lasso_assign_new_gobject(profile->response, lasso_samlp2_response_new());
- response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
- response->ID = lasso_build_unique_id(32);
- lasso_assign_string(response->Version, "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 = (LassoSamlp2StatusResponse*) lasso_samlp2_response_new();
+ if (profile->signature_status) {
+ lasso_check_good_rc(lasso_saml20_profile_init_response(profile, response,
+ LASSO_SAML2_STATUS_CODE_REQUESTER,
+ LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE));
+ rc = profile->signature_status;
+ } else {
+ lasso_check_good_rc(lasso_saml20_profile_init_response(profile, response,
+ LASSO_SAML2_STATUS_CODE_SUCCESS, NULL));
+ }
lasso_assign_string(response->InResponseTo, LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
- /* XXX: adds signature */
- return 0;
+cleanup:
+ return rc;
}
@@ -308,14 +291,15 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
LassoSamlp2AuthnRequest *request;
gboolean matched = TRUE;
GList *assertions = NULL;
- LassoProfile *profile = LASSO_PROFILE(login);
+ LassoProfile *profile = &login->parent;
- request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(login)->request);
+ if (! LASSO_IS_SAMLP2_AUTHN_REQUEST(profile->request))
+ return FALSE;
+ request = LASSO_SAMLP2_AUTHN_REQUEST(profile->request);
if (request->ForceAuthn == TRUE && request->IsPassive == FALSE)
return TRUE;
- assertions = lasso_session_get_assertions(profile->session, NULL);
if (request->RequestedAuthnContext) {
char *comparison = request->RequestedAuthnContext->Comparison;
GList *class_refs = request->RequestedAuthnContext->AuthnContextClassRef;
@@ -323,15 +307,15 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
GList *t1, *t2;
int compa;
- if (comparison == NULL || strcmp(comparison, "exact") == 0) {
+ if (comparison == NULL || g_strcmp0(comparison, "exact") == 0) {
compa = 0;
- } else if (strcmp(comparison, "minimum") == 0) {
+ } else if (g_strcmp0(comparison, "minimum") == 0) {
message(G_LOG_LEVEL_CRITICAL, "'minimum' comparison is not implemented");
compa = 0;
- } else if (strcmp(comparison, "better") == 0) {
+ } else if (g_strcmp0(comparison, "better") == 0) {
message(G_LOG_LEVEL_CRITICAL, "'better' comparison is not implemented");
compa = 0;
- } else if (strcmp(comparison, "maximum") == 0) {
+ } else if (g_strcmp0(comparison, "maximum") == 0) {
message(G_LOG_LEVEL_CRITICAL, "'maximum' comparison is not implemented");
compa = 0;
}
@@ -340,6 +324,7 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
matched = FALSE;
}
+ assertions = lasso_session_get_assertions(profile->session, NULL);
for (t1 = class_refs; t1 && !matched; t1 = g_list_next(t1)) {
class_ref = t1->data;
for (t2 = assertions; t2 && !matched; t2 = g_list_next(t2)) {
@@ -370,7 +355,7 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
method = as->AuthnContext->AuthnContextClassRef;
if (compa == 0) { /* exact */
- if (strcmp(method, class_ref) == 0) {
+ if (g_strcmp0(method, class_ref) == 0) {
matched = TRUE;
break;
}
@@ -383,7 +368,6 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
}
}
}
-
} else {
/* if nothing specific was asked; don't look for any
* particular assertions, one is enough
@@ -391,19 +375,17 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
matched = (profile->session != NULL && \
lasso_session_count_assertions(profile->session) > 0);
}
- g_list_free(assertions);
-
+ if (assertions) {
+ g_list_free(assertions);
+ }
if (matched == FALSE && request->IsPassive == FALSE)
return TRUE;
-
if (profile->identity == NULL && request->IsPassive) {
lasso_saml20_profile_set_response_status_responder(LASSO_PROFILE(login),
LASSO_SAML2_STATUS_CODE_NO_PASSIVE);
return FALSE;
}
-
return FALSE;
-
}
static gboolean
@@ -421,7 +403,7 @@ lasso_saml20_login_must_ask_for_consent_private(LassoLogin *login)
if (name_id_policy) {
char *format = name_id_policy->Format;
- if (strcmp(format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) == 0) {
+ if (g_strcmp0(format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) == 0) {
goto_cleanup_with_rc (FALSE)
}
if (name_id_policy->AllowCreate == FALSE) {
@@ -448,22 +430,22 @@ lasso_saml20_login_must_ask_for_consent_private(LassoLogin *login)
if (consent == NULL)
goto_cleanup_with_rc (FALSE)
- if (strcmp(consent, LASSO_SAML2_CONSENT_OBTAINED) == 0)
+ if (g_strcmp0(consent, LASSO_SAML2_CONSENT_OBTAINED) == 0)
goto_cleanup_with_rc (FALSE)
- if (strcmp(consent, LASSO_SAML2_CONSENT_PRIOR) == 0)
+ if (g_strcmp0(consent, LASSO_SAML2_CONSENT_PRIOR) == 0)
goto_cleanup_with_rc (FALSE)
- if (strcmp(consent, LASSO_SAML2_CONSENT_IMPLICIT) == 0)
+ if (g_strcmp0(consent, LASSO_SAML2_CONSENT_IMPLICIT) == 0)
goto_cleanup_with_rc (FALSE)
- if (strcmp(consent, LASSO_SAML2_CONSENT_EXPLICIT) == 0)
+ if (g_strcmp0(consent, LASSO_SAML2_CONSENT_EXPLICIT) == 0)
goto_cleanup_with_rc (FALSE)
- if (strcmp(consent, LASSO_SAML2_CONSENT_UNAVAILABLE) == 0)
+ if (g_strcmp0(consent, LASSO_SAML2_CONSENT_UNAVAILABLE) == 0)
goto_cleanup_with_rc (TRUE)
- if (strcmp(consent, LASSO_SAML2_CONSENT_INAPPLICABLE) == 0)
+ if (g_strcmp0(consent, LASSO_SAML2_CONSENT_INAPPLICABLE) == 0)
goto_cleanup_with_rc (TRUE)
cleanup:
@@ -498,14 +480,14 @@ lasso_saml20_login_validate_request_msg(LassoLogin *login, gboolean authenticati
}
if (profile->signature_status == LASSO_DS_ERROR_INVALID_SIGNATURE) {
- lasso_saml20_profile_set_response_status_responder(profile,
- LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+ lasso_saml20_profile_set_response_status_requester(profile,
+ LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
return LASSO_LOGIN_ERROR_INVALID_SIGNATURE;
}
if (profile->signature_status == LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
- lasso_saml20_profile_set_response_status_responder(profile,
- LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+ lasso_saml20_profile_set_response_status_requester(profile,
+ LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
return LASSO_LOGIN_ERROR_UNSIGNED_AUTHN_REQUEST;
}
@@ -516,7 +498,7 @@ lasso_saml20_login_validate_request_msg(LassoLogin *login, gboolean authenticati
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
return ret;
}
- /* Only possibility, consent not obtained. */
+ /* PROVIDER_NOT_FOUND, CONSENT_NOT_OBTAINED */
if (ret) {
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
@@ -554,7 +536,7 @@ lasso_saml20_login_process_federation(LassoLogin *login, gboolean is_consent_obt
lasso_assign_string(login->nameIDPolicy, name_id_policy_format);
- if (name_id_policy_format && strcmp(name_id_policy_format,
+ if (name_id_policy_format && g_strcmp0(name_id_policy_format,
LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) == 0) {
goto_cleanup_with_rc (0)
}
@@ -618,6 +600,18 @@ cleanup:
return rc;
}
+static LassoFederation*
+_lasso_login_saml20_get_federation(LassoLogin *login) {
+ LassoFederation *federation = NULL;
+ char *name_id_sp_name_qualifier;
+
+
+ name_id_sp_name_qualifier = lasso_provider_get_sp_name_qualifier(
+ lasso_server_get_provider(login->parent.server, login->parent.remote_providerID));
+ federation = lasso_identity_get_federation(login->parent.identity, name_id_sp_name_qualifier);
+ lasso_release_string(name_id_sp_name_qualifier);
+ return federation;
+}
int
lasso_saml20_login_build_assertion(LassoLogin *login,
@@ -626,44 +620,40 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
const char *notBefore,
const char *notOnOrAfter)
{
- LassoProfile *profile = LASSO_PROFILE(login);
- LassoFederation *federation;
- LassoSaml2Assertion *assertion;
- LassoSaml2AudienceRestriction *audience_restriction;
- LassoSamlp2NameIDPolicy *name_id_policy;
+ LassoProfile *profile = &login->parent;
+#if 0
+ LassoFederation *federation = NULL;
+#endif
+ LassoSaml2Assertion *assertion = NULL;
+ LassoSaml2AudienceRestriction *audience_restriction = NULL;
+ LassoSamlp2NameIDPolicy *name_id_policy = NULL;
LassoSaml2NameID *name_id = NULL;
LassoSaml2AuthnStatement *authentication_statement;
LassoProvider *provider = NULL;
- LassoSaml2EncryptedElement *encrypted_element = NULL;
LassoSamlp2Response *response = NULL;
LassoSamlp2RequestAbstract *request_abstract = NULL;
+ LassoSamlp2AuthnRequest *authn_request = NULL;
+ gboolean do_encrypt_nameid = FALSE;
+ gboolean do_encrypt_assertion = FALSE;
+ int rc = 0;
provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
- if (! LASSO_IS_PROVIDER(provider)) {
- return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
+ if (provider) {
+ do_encrypt_nameid = lasso_provider_get_encryption_mode(provider) &
+ LASSO_ENCRYPTION_MODE_NAMEID;
+ do_encrypt_assertion = lasso_provider_get_encryption_mode(provider) &
+ LASSO_ENCRYPTION_MODE_ASSERTION;
}
- if (profile->request && LASSO_IS_SAMLP2_REQUEST_ABSTRACT(profile->request)) {
- request_abstract = LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request);
+ if (LASSO_IS_SAMLP2_AUTHN_REQUEST(profile->request)) {
+ authn_request = (LassoSamlp2AuthnRequest*)profile->request;
+ request_abstract = &authn_request->parent;
}
+ goto_cleanup_if_fail_with_rc(LASSO_IS_SAMLP2_RESPONSE(profile->response),
+ LASSO_PROFILE_ERROR_MISSING_RESPONSE);
- if (profile->identity && strcmp(login->nameIDPolicy,
- LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) != 0) {
- char *name_id_sp_name_qualifier;
- name_id_sp_name_qualifier = lasso_provider_get_sp_name_qualifier(provider);
-
- if (name_id_sp_name_qualifier != NULL) {
- federation = g_hash_table_lookup(profile->identity->federations,
- name_id_sp_name_qualifier);
- lasso_release_string(name_id_sp_name_qualifier);
- }
- if (federation == NULL) {
- message(G_LOG_LEVEL_WARNING, "can't find federation for identity");
- }
- } else {
- federation = NULL;
- }
+ response = (LassoSamlp2Response*)profile->response;
assertion = LASSO_SAML2_ASSERTION(lasso_saml2_assertion_new());
assertion->ID = lasso_build_unique_id(32);
@@ -678,7 +668,6 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
lasso_assign_string(audience_restriction->Audience, profile->remote_providerID);
lasso_list_add_new_gobject(assertion->Conditions->AudienceRestriction, audience_restriction);
- name_id_policy = LASSO_SAMLP2_AUTHN_REQUEST(profile->request)->NameIDPolicy;
assertion->Subject = LASSO_SAML2_SUBJECT(lasso_saml2_subject_new());
assertion->Subject->SubjectConfirmation = LASSO_SAML2_SUBJECT_CONFIRMATION(
lasso_saml2_subject_confirmation_new());
@@ -691,10 +680,12 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
notBefore);
assertion->Subject->SubjectConfirmation->SubjectConfirmationData->NotOnOrAfter = g_strdup(
notOnOrAfter);
- if (request_abstract) {
- lasso_assign_string(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo,
- request_abstract->ID);
+
+ /* If request is present, refer to it in the response */
+ if (authn_request) {
if (request_abstract->ID) {
+ lasso_assign_string(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo,
+ request_abstract->ID);
/*
* It MUST NOT contain a NotBefore attribute. If
* the containing message is in response to an <AuthnRequest>,
@@ -702,49 +693,46 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
*/
lasso_release_string(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->NotBefore);
}
+ name_id_policy = authn_request->NameIDPolicy;
}
-
- if (name_id_policy && (strcmp(name_id_policy->Format,
- LASSO_SAML2_NAME_IDENTIFIER_FORMAT_EMAIL) == 0 ||
- strcmp(name_id_policy->Format,
- LASSO_SAML2_NAME_IDENTIFIER_FORMAT_UNSPECIFIED) == 0)) {
- /* caller must set the name identifier content afterwards */
- name_id = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new());
- lasso_assign_string(name_id->NameQualifier,
- LASSO_PROVIDER(profile->server)->ProviderID);
- lasso_assign_string(name_id->Format, name_id_policy->Format);
- assertion->Subject->NameID = name_id;
- } else if (federation == NULL ||
- (name_id_policy && strcmp(name_id_policy->Format,
- LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) == 0)) {
- /* transient -> don't use a federation */
- name_id = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
- lasso_build_unique_id(32)));
+ /* TRANSIENT */
+ if (!name_id_policy || g_strcmp0(name_id_policy->Format,
+ LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) == 0) {
+ name_id = (LassoSaml2NameID*)lasso_saml2_name_id_new_with_string(
+ lasso_build_unique_id(32));
lasso_assign_string(name_id->NameQualifier,
- LASSO_PROVIDER(profile->server)->ProviderID);
+ lasso_provider_get_sp_name_qualifier(&profile->server->parent));
lasso_assign_string(name_id->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT);
assertion->Subject->NameID = name_id;
- } else {
- if (provider && name_id_policy && strcmp(name_id_policy->Format,
+ /* FEDERATED */
+ } else if (g_strcmp0(name_id_policy->Format,
+ LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0 ||
+ g_strcmp0(name_id_policy->Format,
+ LASSO_SAML2_NAME_IDENTIFIER_FORMAT_ENCRYPTED) == 0) {
+ LassoFederation *federation;
+
+ federation = _lasso_login_saml20_get_federation(login);
+ goto_cleanup_if_fail_with_rc(federation != NULL,
+ LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
+
+ if (g_strcmp0(name_id_policy->Format,
LASSO_SAML2_NAME_IDENTIFIER_FORMAT_ENCRYPTED) == 0) {
- provider->private_data->encryption_mode |= LASSO_ENCRYPTION_MODE_NAMEID;
+ do_encrypt_nameid = TRUE;
}
lasso_assign_gobject(assertion->Subject->NameID,
federation->local_nameIdentifier);
- }
-
- /* Encrypt NameID */
- if (provider && provider->private_data->encryption_mode & LASSO_ENCRYPTION_MODE_NAMEID
- && provider->private_data->encryption_public_key != NULL
- && assertion->Subject->NameID->content != NULL) {
- encrypted_element = LASSO_SAML2_ENCRYPTED_ELEMENT(lasso_node_encrypt(
- LASSO_NODE(assertion->Subject->NameID),
- provider->private_data->encryption_public_key,
- provider->private_data->encryption_sym_key_type));
- if (encrypted_element != NULL) {
- assertion->Subject->EncryptedID = encrypted_element;
- g_object_unref(assertion->Subject->NameID);
- assertion->Subject->NameID = NULL;
+ /* ALL OTHER KIND OF NAME ID FORMATS */
+ } else {
+ /* caller must set the name identifier content afterwards */
+ name_id = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new());
+ lasso_assign_string(name_id->NameQualifier,
+ LASSO_PROVIDER(profile->server)->ProviderID);
+ lasso_assign_string(name_id->Format, name_id_policy->Format);
+ assertion->Subject->NameID = name_id;
+ if (do_encrypt_nameid) {
+ message(G_LOG_LEVEL_WARNING, "NameID encryption is currently not "
+ "supported with non transient or persisent NameID format");
+ do_encrypt_nameid = FALSE;
}
}
@@ -755,20 +743,34 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
lasso_saml2_authn_context_new());
authentication_statement->AuthnContext->AuthnContextClassRef = g_strdup(
authenticationMethod);
-
- assertion->AuthnStatement = g_list_append(NULL, authentication_statement);
+ lasso_list_add_new_gobject(assertion->AuthnStatement, authentication_statement);
/* Save signing material in assertion private datas to be able to sign later */
- lasso_server_saml2_assertion_setup_signature(profile->server, assertion);
+ lasso_check_good_rc(lasso_server_saml2_assertion_setup_signature(profile->server,
+ assertion));
+
+
+ /* Encrypt NameID */
+ if (do_encrypt_nameid) {
+ /* 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);
+
+ assertion->Subject->EncryptedID = (LassoSaml2EncryptedElement*)lasso_node_encrypt(
+ (LassoNode*)assertion->Subject->NameID,
+ lasso_provider_get_encryption_public_key(provider),
+ lasso_provider_get_encryption_sym_key_type(provider));
+ goto_cleanup_if_fail_with_rc(assertion->Subject->EncryptedID == NULL,
+ LASSO_DS_ERROR_ENCRYPTION_FAILED);
+ lasso_release_gobject(assertion->Subject->NameID);
+ }
/* Save encryption material in assertion private datas to be able to encrypt later */
- if (provider && provider->private_data->encryption_mode & LASSO_ENCRYPTION_MODE_ASSERTION
- && provider->private_data->encryption_public_key != NULL) {
+ if (do_encrypt_assertion) {
assertion->encryption_activated = TRUE;
- assertion->encryption_public_key_str = g_strdup(
- provider->private_data->encryption_public_key_str);
+ lasso_assign_string(assertion->encryption_public_key_str,
+ provider->private_data->encryption_public_key_str);
assertion->encryption_sym_key_type =
- provider->private_data->encryption_sym_key_type;
+ lasso_provider_get_encryption_sym_key_type(provider);
}
/* store assertion in session object */
@@ -780,11 +782,11 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
LASSO_NODE(assertion));
response = LASSO_SAMLP2_RESPONSE(profile->response);
- lasso_list_add_new_gobject(response->Assertion, assertion);
-
+ lasso_list_add_gobject(response->Assertion, assertion);
lasso_assign_gobject(login->private_data->saml2_assertion, assertion);
-
- return 0;
+cleanup:
+ lasso_release_gobject(assertion);
+ return rc;
}
gint
@@ -792,12 +794,12 @@ lasso_saml20_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_me
{
LassoProfile *profile;
LassoProvider *remote_provider;
- char *artifact;
char *url;
LassoSaml2Assertion *assertion;
LassoSamlp2StatusResponse *response;
+ int rc = 0;
- profile = LASSO_PROFILE(login);
+ profile = &login->parent;
if (profile->remote_providerID == NULL)
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
@@ -806,54 +808,36 @@ lasso_saml20_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_me
return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
}
+ if (! LASSO_IS_SAMLP2_RESPONSE(profile->response)) {
+ return critical_error(LASSO_PROFILE_ERROR_MISSING_RESPONSE);
+ }
+ response = (LassoSamlp2StatusResponse*)profile->response;
+ /* XXX: why checking now ? */
+ if (response->Status == NULL || response->Status->StatusCode == NULL
+ || response->Status->StatusCode->Value == NULL) {
+ return critical_error(LASSO_PROFILE_ERROR_MISSING_STATUS_CODE);
+ }
+
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);
url = lasso_saml20_login_get_assertion_consumer_service_url(login, remote_provider);
assertion = login->private_data->saml2_assertion;
- if (LASSO_IS_SAML2_ASSERTION(assertion) == TRUE) {
- assertion->Subject->SubjectConfirmation->SubjectConfirmationData->Recipient =
- g_strdup(url);
- }
-
- artifact = lasso_saml20_profile_generate_artifact(profile, 1);
- lasso_assign_string(login->assertionArtifact, artifact);
- if (http_method == LASSO_HTTP_METHOD_ARTIFACT_GET) {
- gchar *query;
-
- if (profile->msg_relayState) {
- query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, "RelayState",
- profile->msg_relayState, NULL);
- } else {
- query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, NULL);
- }
- lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
- lasso_release_string(query);
- } else {
- /* XXX: ARTIFACT POST */
- }
- lasso_release_string(url);
+ if (LASSO_IS_SAML2_ASSERTION(assertion) && url) {
+ LassoSaml2SubjectConfirmationData *subject_confirmation_data;
- response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
- if (response->Status == NULL || response->Status->StatusCode == NULL
- || response->Status->StatusCode->Value == NULL) {
- return critical_error(LASSO_PROFILE_ERROR_MISSING_STATUS_CODE);
+ subject_confirmation_data =
+ lasso_saml2_assertion_get_subject_confirmation_data(assertion, TRUE);
+ lasso_assign_string(subject_confirmation_data->Recipient, url);
}
- if (strcmp(LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->Status->StatusCode->Value,
- "samlp:Success") != 0) {
- if (profile->session == NULL)
- profile->session = lasso_session_new();
-
- lasso_session_add_status(profile->session, profile->remote_providerID,
- g_object_ref(LASSO_SAMLP2_STATUS_RESPONSE(
- profile->response)->Status));
- } else {
- lasso_session_remove_status(profile->session, profile->remote_providerID);
- }
+ lasso_check_good_rc(lasso_saml20_profile_build_response_msg(profile, NULL, http_method,
+ url));
- return 0;
+cleanup:
+ lasso_release_string(url);
+ return rc;
}
@@ -870,23 +854,15 @@ gint
lasso_saml20_login_build_request_msg(LassoLogin *login)
{
LassoProfile *profile;
- LassoProvider *remote_provider;
-
- profile = LASSO_PROFILE(login);
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file,
- profile->server->private_key);
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file,
- profile->server->certificate);
- lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->request));
-
- 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);
+ profile = &login->parent;
+ if (_lasso_login_must_sign_non_authn_request(login)) {
+ lasso_profile_saml20_setup_message_signature(profile, profile->request);
+ } else {
+ lasso_node_remove_signature(profile->request);
}
- lasso_assign_new_string(profile->msg_url, lasso_provider_get_metadata_one(remote_provider,
- "ArtifactResolutionService SOAP"));
- return 0;
+ return lasso_saml20_profile_build_request_msg(profile, "ArtifactResolutionService",
+ LASSO_HTTP_METHOD_SOAP, NULL);
}
gint
@@ -910,25 +886,13 @@ lasso_saml20_login_build_response_msg(LassoLogin *login)
LassoProfile *profile = LASSO_PROFILE(login);
LassoProvider *remote_provider;
LassoSaml2Assertion *assertion;
+ int rc = 0;
if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP) {
const char *assertionConsumerURL;
- if (profile->server->certificate) {
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->sign_type =
- LASSO_SIGNATURE_TYPE_WITHX509;
- } else {
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->sign_type =
- LASSO_SIGNATURE_TYPE_SIMPLE;
- }
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->sign_method =
- LASSO_SIGNATURE_METHOD_RSA_SHA1;
-
- lasso_assign_string(LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->private_key_file,
- profile->server->private_key);
- lasso_assign_string(LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->certificate_file,
- profile->server->certificate);
-
+ lasso_check_good_rc(lasso_profile_saml20_setup_message_signature(profile,
+ profile->response));
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);
@@ -945,10 +909,13 @@ lasso_saml20_login_build_response_msg(LassoLogin *login)
/* build an ECP SOAP Response */
lasso_assign_new_string(profile->msg_body, lasso_node_export_to_ecp_soap_response(
LASSO_NODE(profile->response), assertionConsumerURL));
- return 0;
+ return rc;
}
return lasso_saml20_profile_build_artifact_response(LASSO_PROFILE(login));
+
+cleanup:
+ return rc;
}
gint
@@ -957,7 +924,6 @@ lasso_saml20_login_process_paos_response_msg(LassoLogin *login, gchar *msg)
LassoProfile *profile;
int rc1, rc2;
- lasso_bad_param(LOGIN, login);
lasso_null_param(msg);
profile = LASSO_PROFILE(login);
@@ -989,14 +955,13 @@ lasso_saml20_login_process_authn_response_msg(LassoLogin *login, gchar *authn_re
int rc1, rc2, message_signature_status;
LassoSamlp2Response *samlp2_response = NULL;
- lasso_bad_param(LOGIN, login);
lasso_null_param(authn_response_msg);
/* parse the message */
profile = LASSO_PROFILE(login);
samlp2_response = (LassoSamlp2Response*)lasso_samlp2_response_new();
rc1 = lasso_saml20_profile_process_any_response(profile,
- (LassoSamlp2StatusResponse*)samlp2_response,
+ (LassoSamlp2StatusResponse*)samlp2_response, NULL,
authn_response_msg);
message_signature_status = profile->signature_status;
@@ -1043,7 +1008,6 @@ lasso_saml20_login_check_assertion_signature(LassoLogin *login,
LassoProvider *remote_provider;
int rc = 0;
- lasso_bad_param(LOGIN, login);
lasso_bad_param(SAML2_ASSERTION, assertion);
profile = (LassoProfile*)login;
@@ -1055,7 +1019,7 @@ lasso_saml20_login_check_assertion_signature(LassoLogin *login,
if (! Issuer || /* No issuer */
! Issuer->content || /* No issuer content */
(Issuer->Format &&
- strcmp(Issuer->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_ENTITY) != 0))
+ g_strcmp0(Issuer->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_ENTITY) != 0))
/* Issuer format is not entity */
{
rc = LASSO_PROFILE_ERROR_MISSING_ISSUER;
@@ -1121,19 +1085,19 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
}
status_value = response->Status->StatusCode->Value;
- if (status_value && strcmp(status_value, LASSO_SAML2_STATUS_CODE_SUCCESS) != 0) {
- if (strcmp(status_value, LASSO_SAML2_STATUS_CODE_REQUEST_DENIED) == 0)
+ if (status_value && g_strcmp0(status_value, LASSO_SAML2_STATUS_CODE_SUCCESS) != 0) {
+ if (g_strcmp0(status_value, LASSO_SAML2_STATUS_CODE_REQUEST_DENIED) == 0)
return LASSO_LOGIN_ERROR_REQUEST_DENIED;
- if (strcmp(status_value, LASSO_SAML2_STATUS_CODE_RESPONDER) == 0) {
+ if (g_strcmp0(status_value, LASSO_SAML2_STATUS_CODE_RESPONDER) == 0) {
/* samlp:Responder */
if (response->Status->StatusCode->StatusCode &&
response->Status->StatusCode->StatusCode->Value) {
status_value = response->Status->StatusCode->StatusCode->Value;
- if (strcmp(status_value,
+ if (g_strcmp0(status_value,
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST) == 0) {
return LASSO_LOGIN_ERROR_FEDERATION_NOT_FOUND;
}
- if (strcmp(status_value,
+ if (g_strcmp0(status_value,
LASSO_LIB_STATUS_CODE_UNKNOWN_PRINCIPAL) == 0) {
return LASSO_LOGIN_ERROR_UNKNOWN_PRINCIPAL;
}
@@ -1204,7 +1168,7 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
assertion->Subject->SubjectConfirmation == NULL ||
assertion->Subject->SubjectConfirmation->SubjectConfirmationData == NULL ||
assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo == NULL ||
- strcmp(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo, login->private_data->request_id) != 0)) {
+ g_strcmp0(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo, login->private_data->request_id) != 0)) {
return LASSO_LOGIN_ERROR_ASSERTION_DOES_NOT_MATCH_REQUEST_ID;
}
@@ -1256,7 +1220,7 @@ lasso_saml20_login_accept_sso(LassoLogin *login)
ta = t->data;
- if (strcmp(ta->ID, assertion->ID) == 0) {
+ if (g_strcmp0(ta->ID, assertion->ID) == 0) {
g_list_free(previous_assertions);
return LASSO_LOGIN_ERROR_ASSERTION_REPLAY;
}
@@ -1273,7 +1237,9 @@ lasso_saml20_login_accept_sso(LassoLogin *login)
}
/* create federation, only if nameidentifier format is Federated */
- if (ni && ni->Format && strcmp(ni->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0) {
+ if (ni && ni->Format
+ && g_strcmp0(ni->Format,
+ LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0) {
federation = lasso_federation_new(LASSO_PROFILE(login)->remote_providerID);
lasso_assign_gobject(federation->local_nameIdentifier, ni);
@@ -1287,65 +1253,57 @@ lasso_saml20_login_accept_sso(LassoLogin *login)
gint
lasso_saml20_login_build_authn_response_msg(LassoLogin *login)
{
- LassoProfile *profile = LASSO_PROFILE(login);
- LassoProvider *remote_provider;
- LassoSaml2Assertion *assertion;
+ LassoProfile *profile;
+ LassoProvider *remote_provider = NULL;
+ LassoSaml2Assertion *assertion = NULL;
+ LassoHttpMethod http_method;
+ char *url = NULL;
+ int rc = 0;
+
+ profile = &login->parent;
if (login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST &&
login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT) {
return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
}
- if (profile->server->certificate) {
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->sign_type =
- LASSO_SIGNATURE_TYPE_WITHX509;
+ if (_lasso_login_must_sign_non_authn_request(login)) {
+ lasso_check_good_rc(lasso_profile_saml20_setup_message_signature(profile,
+ profile->response));
} else {
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->sign_type =
- LASSO_SIGNATURE_TYPE_SIMPLE;
+ lasso_node_remove_signature(profile->response);
}
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->sign_method =
- LASSO_SIGNATURE_METHOD_RSA_SHA1;
-
- lasso_assign_string(LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->private_key_file,
- profile->server->private_key);
- lasso_assign_string(LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->certificate_file,
- profile->server->certificate);
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);
- lasso_assign_new_string(profile->msg_url, lasso_saml20_login_get_assertion_consumer_service_url(
- login, remote_provider));
- if (profile->msg_url == NULL) {
- return LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL;
- }
+ url = lasso_saml20_login_get_assertion_consumer_service_url(login, remote_provider);
assertion = login->private_data->saml2_assertion;
- if (LASSO_IS_SAML2_ASSERTION(assertion) == TRUE) {
- assertion->Subject->SubjectConfirmation->SubjectConfirmationData->Recipient =
- g_strdup(profile->msg_url);
- }
+ if (LASSO_IS_SAML2_ASSERTION(assertion) && url) {
+ LassoSaml2SubjectConfirmationData *subject_confirmation_data;
-
- if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST) {
- /* build an lib:AuthnResponse base64 encoded */
- lasso_assign_new_string(profile->msg_body, lasso_node_export_to_base64(LASSO_NODE(profile->response)));
- } else {
- int rc;
- char *acsUrl;
-
- acsUrl = profile->msg_url;
- rc = lasso_saml20_profile_build_http_redirect(profile, profile->response, 1, acsUrl);
- lasso_release_string(acsUrl);
- if (rc != 0) {
- return rc;
- }
+ subject_confirmation_data =
+ lasso_saml2_assertion_get_subject_confirmation_data(assertion, TRUE);
+ lasso_assign_string(subject_confirmation_data->Recipient, url);
}
+ switch (login->protocolProfile) {
+ case LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST:
+ http_method = LASSO_HTTP_METHOD_POST;
+ break;
+ case LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT:
+ http_method = LASSO_HTTP_METHOD_REDIRECT;
+ break;
+ default:
+ g_critical("Cannot happen");
+ break;
+ }
+ lasso_check_good_rc(lasso_saml20_profile_build_request_msg(profile, NULL, http_method, url));
- return 0;
-
+cleanup:
+ return rc;
}
static char*
@@ -1394,7 +1352,6 @@ lasso_saml20_login_init_idp_initiated_authn_request(LassoLogin *login,
gchar *default_name_id_format = NULL;
int rc = 0;
- lasso_bad_param(LOGIN, login);
profile = &login->parent;
lasso_extract_node_or_fail(server, lasso_profile_get_server(profile), SERVER,
LASSO_PROFILE_ERROR_MISSING_SERVER);
@@ -1402,10 +1359,7 @@ lasso_saml20_login_init_idp_initiated_authn_request(LassoLogin *login,
if (! LASSO_IS_PROVIDER(provider))
return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
- rc = lasso_login_init_authn_request(login, remote_providerID, LASSO_HTTP_METHOD_POST);
- if (rc)
- return rc;
-
+ lasso_check_good_rc(lasso_login_init_authn_request(login, remote_providerID, LASSO_HTTP_METHOD_ANY));
lasso_release_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->Issuer->content,
remote_providerID);
diff --git a/lasso/saml-2.0/loginprivate.h b/lasso/saml-2.0/loginprivate.h
index 0e3f9a7d..b17a4b99 100644
--- a/lasso/saml-2.0/loginprivate.h
+++ b/lasso/saml-2.0/loginprivate.h
@@ -32,7 +32,7 @@ extern "C" {
#include "../id-ff/login.h"
gint lasso_saml20_login_init_authn_request(LassoLogin *login, LassoHttpMethod http_method);
-gint lasso_saml20_login_build_authn_request_msg(LassoLogin *login, LassoProvider *remote_provider);
+gint lasso_saml20_login_build_authn_request_msg(LassoLogin *login);
gint lasso_saml20_login_build_authn_response_msg(LassoLogin *login);
gint lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *authn_request_msg);
gboolean lasso_saml20_login_must_authenticate(LassoLogin *login);
diff --git a/lasso/saml-2.0/logout.c b/lasso/saml-2.0/logout.c
index 386a1f3e..20717295 100644
--- a/lasso/saml-2.0/logout.c
+++ b/lasso/saml-2.0/logout.c
@@ -45,156 +45,90 @@
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 = LASSO_PROFILE(logout);
- LassoNode *assertion_n;
- LassoSaml2Assertion *assertion;
- LassoSaml2NameID *name_id;
- LassoSession *session;
- LassoSamlp2RequestAbstract *request;
- LassoSaml2EncryptedElement *encrypted_element = NULL;
- char *assertion_SessionIndex = NULL;
+ LassoProfile *profile = &logout->parent;
+ LassoNode *assertion_n = NULL;
+ LassoSaml2Assertion *assertion = NULL;
+ //LassoSaml2NameID *name_id = NULL;
+ LassoSession *session = NULL;
+ //LassoSamlp2RequestAbstract *request = NULL;
+ //LassoSaml2EncryptedElement *encrypted_element = NULL;
+ LassoSamlp2LogoutRequest *logout_request = NULL;
+ //char *assertion_SessionIndex = NULL;
+ int rc = 0;
+
+ logout_request = (LassoSamlp2LogoutRequest*) lasso_samlp2_logout_request_new();
+
+ lasso_check_good_rc(lasso_saml20_init_request(profile,
+ remote_provider->ProviderID,
+ FALSE,
+ &logout_request->parent,
+ http_method,
+ LASSO_MD_PROTOCOL_TYPE_SINGLE_LOGOUT));
/* 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);
}
+ lasso_ref(assertion_n);
+ assertion = (LassoSaml2Assertion*)assertion_n;
- assertion = LASSO_SAML2_ASSERTION(assertion_n);
-
- if (assertion->Subject == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_SUBJECT;
- }
-
- if (assertion->Subject->NameID == NULL) {
- return LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER;
- }
-
- name_id = assertion->Subject->NameID;
- /* Just send back the NameID from the assertion. */
- lasso_assign_gobject(profile->nameIdentifier, 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) {
- lasso_assign_string(profile->remote_providerID,
- 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;
- }
- }
-
- lasso_assign_new_gobject(profile->request, lasso_samlp2_logout_request_new());
- request = LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request);
- lasso_assign_new_string(request->ID, lasso_build_unique_id(32));
- lasso_assign_string(request->Version, "2.0");
- lasso_assign_new_gobject(request->Issuer,
- LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
- LASSO_PROVIDER(profile->server)->ProviderID)));
- lasso_assign_new_string(request->IssueInstant, lasso_get_current_time());
-
- lasso_assign_gobject(LASSO_SAMLP2_LOGOUT_REQUEST(request)->NameID, profile->nameIdentifier);
-
- /* set the session index */
- if (assertion->AuthnStatement) {
- if (! LASSO_IS_SAML2_AUTHN_STATEMENT(assertion->AuthnStatement->data)) {
-
- return LASSO_PROFILE_ERROR_BAD_SESSION_DUMP;
- }
- assertion_SessionIndex =
- ((LassoSaml2AuthnStatement*)assertion->AuthnStatement->data)->SessionIndex;
- if (assertion_SessionIndex) {
- lasso_assign_string(LASSO_SAMLP2_LOGOUT_REQUEST(request)->SessionIndex, assertion_SessionIndex);
- }
- }
+ /* set the nameid */
+ lasso_assign_gobject(logout_request->NameID, profile->nameIdentifier);
+ /* Encrypt NameID */
+ rc = lasso_saml20_profile_setup_encrypted_node(remote_provider, (LassoNode**)&logout_request->NameID,
+ (LassoNode**)&logout_request->EncryptedID);
+ /* set the session index if one is found */
+ lasso_assign_string(logout_request->SessionIndex,
+ _lasso_saml2_assertion_get_session_index(assertion));
+ lasso_session_remove_assertion(profile->session,
+ profile->remote_providerID);
+cleanup:
+ /* special case: we suppose REDIRECT is the last resort method, so we force assertion
+ * removal and create a possible response message with a second level status of PARTIAL. */
+ if (rc == LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE
+ && http_method == LASSO_HTTP_METHOD_REDIRECT) {
+ lasso_session_remove_assertion(profile->session,
+ profile->remote_providerID);
+ if (logout->initial_remote_providerID && logout->initial_request) {
+ LassoSamlp2StatusResponse *response;
- /* Encrypt NameID */
- if (remote_provider &&
- remote_provider->private_data->encryption_mode & LASSO_ENCRYPTION_MODE_NAMEID
- && remote_provider->private_data->encryption_public_key != NULL) {
- encrypted_element = LASSO_SAML2_ENCRYPTED_ELEMENT(lasso_node_encrypt(
- LASSO_NODE(LASSO_SAMLP2_LOGOUT_REQUEST(request)->NameID),
- remote_provider->private_data->encryption_public_key,
- remote_provider->private_data->encryption_sym_key_type));
- if (encrypted_element != NULL) {
- lasso_assign_new_gobject(LASSO_SAMLP2_LOGOUT_REQUEST(request)->EncryptedID, encrypted_element);
- lasso_release_gobject(LASSO_SAMLP2_LOGOUT_REQUEST(request)->NameID)
+ logout->private_data->partial_logout = TRUE;
+ lasso_assign_string(profile->remote_providerID,
+ logout->initial_remote_providerID);
+ response = (LassoSamlp2StatusResponse*) lasso_samlp2_logout_response_new();
+ /* ignore return code */
+ lasso_saml20_profile_init_response(profile, response, LASSO_SAML2_STATUS_CODE_SUCCESS,
+ LASSO_SAML2_STATUS_CODE_PARTIAL_LOGOUT);
+ lasso_release_gobject(response);
}
}
-
- logout->initial_http_request_method = http_method;
-
- return 0;
+ lasso_release_gobject(logout_request);
+ lasso_release_gobject(assertion_n);
+ return rc;
}
-
int
-lasso_saml20_logout_build_request_msg(LassoLogout *logout, LassoProvider *remote_provider)
+lasso_saml20_logout_build_request_msg(LassoLogout *logout)
{
- LassoProfile *profile = LASSO_PROFILE(logout);
-
- LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->sign_method =
- LASSO_SIGNATURE_METHOD_RSA_SHA1;
- if (profile->server->certificate) {
- LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->sign_type =
- LASSO_SIGNATURE_TYPE_WITHX509;
- } else {
- LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->sign_type =
- LASSO_SIGNATURE_TYPE_SIMPLE;
- }
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file,
- profile->server->private_key);
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file,
- profile->server->certificate);
-
- if (logout->initial_http_request_method == LASSO_HTTP_METHOD_SOAP) {
- lasso_assign_new_string(profile->msg_url,
- lasso_provider_get_metadata_one(remote_provider, "SingleLogoutService SOAP"));
- lasso_assign_string(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->Destination,
- profile->msg_url);
- lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->request));
- return 0;
- }
- if (logout->initial_http_request_method == LASSO_HTTP_METHOD_REDIRECT) {
- return lasso_saml20_build_http_redirect_query_simple(profile, profile->request,
- TRUE, "SingleLogoutService", FALSE);
- }
+ LassoProfile *profile = &logout->parent;
- /* XXX: artifact support */
-
- return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
+ return lasso_saml20_profile_build_request_msg(profile, "SingleLogoutService",
+ logout->parent.http_request_method, NULL);
}
int
@@ -216,12 +150,13 @@ lasso_saml20_logout_process_request_msg(LassoLogout *logout, char *request_msg)
if (rc1 && ! logout_request) {
return rc1;
}
+ /* remember initial request method, for setting it for generating response */
+ logout->initial_http_request_method = profile->http_request_method;
rc2 = lasso_saml20_profile_process_name_identifier_decryption(profile,
&logout_request->NameID,
&logout_request->EncryptedID);
-
lasso_release_gobject(logout_request);
if (profile->signature_status) {
return profile->signature_status;
@@ -230,7 +165,6 @@ lasso_saml20_logout_process_request_msg(LassoLogout *logout, char *request_msg)
return rc1;
}
return rc2;
-
}
int
@@ -244,41 +178,24 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
LassoSaml2Assertion *assertion;
LassoSamlp2LogoutRequest *logout_request;
char *assertion_SessionIndex = NULL;
+ int rc = 0;
if (LASSO_IS_SAMLP2_LOGOUT_REQUEST(profile->request) == FALSE)
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
-
logout_request = (LassoSamlp2LogoutRequest*)profile->request;
+ /* check the issuer */
lasso_assign_string(profile->remote_providerID,
- LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->Issuer->content);
-
- /* get the provider */
+ 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);
}
- lasso_assign_new_gobject(profile->response, lasso_samlp2_logout_response_new());
- response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
- lasso_assign_new_string(response->ID, lasso_build_unique_id(32));
- lasso_assign_string(response->Version, "2.0");
- lasso_assign_new_gobject(response->Issuer,
- LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
- LASSO_PROVIDER(profile->server)->ProviderID)));
- lasso_assign_new_string(response->IssueInstant, lasso_get_current_time());
- lasso_assign_string(response->InResponseTo,
- LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
- lasso_saml20_profile_set_response_status_success(profile, NULL);
-
- 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);
+ /* create the response */
+ response = (LassoSamlp2StatusResponse*)lasso_samlp2_logout_response_new();
+ lasso_check_good_rc(lasso_saml20_profile_init_response(profile, response,
+ LASSO_SAML2_STATUS_CODE_SUCCESS, NULL));
/* verify signature status */
if (profile->signature_status != 0) {
@@ -313,7 +230,8 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
/* 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");
+ LASSO_SAML2_STATUS_CODE_RESPONDER,
+ "http://lasso.entrouvert.org/error/MalformedAssertion");
return LASSO_PROFILE_ERROR_MISSING_SUBJECT;
}
@@ -335,7 +253,7 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
((LassoSaml2AuthnStatement*)assertion->AuthnStatement->data)->SessionIndex;
if (g_strcmp0(logout_request->SessionIndex, assertion_SessionIndex) != 0) {
lasso_saml20_profile_set_response_status_responder(profile,
- LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL);
+ LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
}
}
@@ -371,9 +289,9 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
lasso_transfer_gobject(logout->initial_response, profile->response);
}
- return 0;
-
-
+cleanup:
+ lasso_release_gobject(response);
+ return rc;
}
static void
@@ -407,93 +325,41 @@ lasso_saml20_logout_build_response_msg(LassoLogout *logout)
{
LassoProfile *profile = LASSO_PROFILE(logout);
LassoSamlp2StatusResponse *response;
+ int rc = 0;
if (profile->response == NULL) {
/* no response set here means request denied */
- lasso_assign_new_gobject(profile->response, lasso_samlp2_logout_response_new());
- response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
- lasso_assign_new_string(response->ID, lasso_build_unique_id(32));
- lasso_assign_string(response->Version, "2.0");
- lasso_assign_new_gobject(response->Issuer, LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
- LASSO_PROVIDER(profile->server)->ProviderID)));
- lasso_assign_new_string(response->IssueInstant, lasso_get_current_time());
- if (profile->request) {
- lasso_assign_string(response->InResponseTo,
- LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
- }
- lasso_saml20_profile_set_response_status_responder(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;
- }
- lasso_assign_string(response->private_key_file, profile->server->private_key);
- lasso_assign_string(response->certificate_file, profile->server->certificate);
+ response = (LassoSamlp2StatusResponse*) lasso_samlp2_logout_response_new();
+ lasso_check_good_rc(lasso_saml20_profile_init_response(profile, response,
+ LASSO_SAML2_STATUS_CODE_RESPONDER,
+ LASSO_SAML2_STATUS_CODE_REQUEST_DENIED));
}
/* build logout response message */
- if (profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
- lasso_release_string(profile->msg_url);
- lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->response));
- return 0;
- }
+ /* FIXME: should allow to override default response method, should just match that
+ * request/response are of the same type synchronous or asynchronous */
+ rc = lasso_saml20_profile_build_response_msg(profile, "SingleLogoutService",
+ logout->initial_http_request_method, NULL);
- if (profile->http_request_method == LASSO_HTTP_METHOD_REDIRECT) {
- return lasso_saml20_build_http_redirect_query_simple(profile, profile->response, TRUE, "SingleLogoutService", TRUE);
- }
-
- return LASSO_PROFILE_ERROR_MISSING_REQUEST;
+cleanup:
+ lasso_release_gobject(response);
+ return rc;
}
int
lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *response_msg)
{
- LassoProfile *profile = LASSO_PROFILE(logout);
+ LassoProfile *profile = &logout->parent;
LassoHttpMethod response_method;
LassoProvider *remote_provider = NULL;
LassoSamlp2StatusResponse *response = NULL;
- LassoMessageFormat format;
char *status_code_value = NULL;
- int rc;
-
- lasso_assign_new_gobject(profile->response, lasso_samlp2_logout_response_new());
- format = lasso_node_init_from_message(LASSO_NODE(profile->response), response_msg);
-
- switch (format) {
- case LASSO_MESSAGE_FORMAT_SOAP:
- response_method = LASSO_HTTP_METHOD_SOAP;
- break;
- case LASSO_MESSAGE_FORMAT_QUERY:
- response_method = LASSO_HTTP_METHOD_REDIRECT;
- break;
- default:
- return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
- }
+ int rc = 0;
- lasso_assign_string(profile->remote_providerID,
- LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->Issuer->content);
-
- /* 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);
- }
-
- /* verify signature */
- rc = lasso_provider_verify_signature(remote_provider, response_msg, "ID", format);
-
- response = LASSO_SAMLP2_STATUS_RESPONSE(profile->response);
-
- if (response->Status == NULL || response->Status->StatusCode == NULL
- || response->Status->StatusCode->Value == NULL) {
- rc = LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
- } else {
- status_code_value = response->Status->StatusCode->Value;
- }
+ response = (LassoSamlp2StatusResponse*)profile->response;
+ lasso_check_good_rc(lasso_saml20_profile_process_any_response(profile, response, &response_method, response_msg));
+ status_code_value = response->Status->StatusCode->Value;
if (status_code_value && strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_SUCCESS) != 0) {
/* If at SP, if the request method was a SOAP type, then
* rebuild the request message with HTTP method */
@@ -507,6 +373,7 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
}
if (status_code_value == NULL) {
rc = LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
+ goto cleanup;
}
}
if (strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_REQUEST_DENIED) == 0) {
@@ -515,15 +382,16 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
lasso_session_remove_assertion(
profile->session, profile->remote_providerID);
rc = LASSO_LOGOUT_ERROR_REQUEST_DENIED;
+ goto cleanup;
}
if (strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL) == 0) {
rc = LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
+ goto cleanup;
}
rc = LASSO_PROFILE_ERROR_STATUS_NOT_SUCCESS;
+ goto cleanup;
}
- /* LogoutResponse status code value is ok */
- /* XXX: handle RelayState if necessary */
/* if SOAP method or, if IDP provider type and HTTP Redirect,
* then remove assertion */
@@ -543,7 +411,7 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
if (logout->initial_remote_providerID &&
lasso_session_count_assertions(profile->session) == 0) {
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
- if (remote_provider->role == LASSO_PROVIDER_ROLE_SP) {
+ if (remote_provider->role & LASSO_PROVIDER_ROLE_SP) {
lasso_transfer_string(profile->remote_providerID,
logout->initial_remote_providerID);
lasso_transfer_gobject(profile->request, logout->initial_request);
@@ -565,6 +433,8 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
lasso_session_remove_assertion(profile->session, profile->remote_providerID);
}
+cleanup:
+ lasso_release_gobject(response);
return rc;
}
diff --git a/lasso/saml-2.0/logoutprivate.h b/lasso/saml-2.0/logoutprivate.h
index b3452abb..ae10d918 100644
--- a/lasso/saml-2.0/logoutprivate.h
+++ b/lasso/saml-2.0/logoutprivate.h
@@ -34,7 +34,7 @@ extern "C" {
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_build_request_msg(LassoLogout *logout);
int lasso_saml20_logout_process_request_msg(LassoLogout *logout, char *request_msg);
diff --git a/lasso/saml-2.0/name_id_management.c b/lasso/saml-2.0/name_id_management.c
index 99c12e18..c9a43d73 100644
--- a/lasso/saml-2.0/name_id_management.c
+++ b/lasso/saml-2.0/name_id_management.c
@@ -53,7 +53,10 @@
* @http_method: if set, then it get the protocol profile in metadata
* corresponding of this HTTP request method.
*
- * Initializes a new Name Id Management Request.
+ * Initializes a new Name Id Management Request. If @new_name_id is NULL, it is a Termination
+ * request, if not and we are an IdP is a NameID change request, if we are a SP, it is a request to
+ * add a SP provided Id to the NameID of the IdP. It can be useful if the SP do not want to store
+ * the federation, instead he can export its own identifiers to the IdP.
*
* Return value: 0 on success; or a negative value otherwise.
**/
@@ -73,10 +76,8 @@ lasso_name_id_management_init_request(LassoNameIdManagement *name_id_management,
request = (LassoSamlp2RequestAbstract*)lasso_samlp2_manage_name_id_request_new();
manage_name_id_request = LASSO_SAMLP2_MANAGE_NAME_ID_REQUEST(request);
- rc = lasso_saml20_init_request(profile, remote_provider_id, TRUE, request, http_method,
- LASSO_MD_PROTOCOL_TYPE_MANAGE_NAME_ID);
- if (rc)
- goto cleanup;
+ lasso_check_good_rc(lasso_saml20_init_request(profile, remote_provider_id, TRUE, request,
+ http_method, LASSO_MD_PROTOCOL_TYPE_MANAGE_NAME_ID));
lasso_assign_gobject(manage_name_id_request->NameID, (LassoSaml2NameID*)profile->nameIdentifier);
if (new_name_id) {
@@ -84,6 +85,11 @@ lasso_name_id_management_init_request(LassoNameIdManagement *name_id_management,
} else {
lasso_assign_new_gobject(manage_name_id_request->Terminate,
LASSO_SAMLP2_TERMINATE(lasso_samlp2_terminate_new()));
+ /* if we are the IdP we can apply termination immediately. */
+ if (profile->server->parent.role & LASSO_PROVIDER_ROLE_IDP) {
+ lasso_identity_remove_federation(profile->identity,
+ profile->remote_providerID);
+ }
}
cleanup:
@@ -106,7 +112,7 @@ lasso_name_id_management_build_request_msg(LassoNameIdManagement *name_id_manage
{
lasso_bad_param(NAME_ID_MANAGEMENT, name_id_management);
- return lasso_saml20_profile_build_request_msg(&name_id_management->parent, "ManageNameIDService", FALSE);
+ return lasso_saml20_profile_build_request_msg(&name_id_management->parent, "ManageNameIDService", name_id_management->parent.http_request_method, NULL);
}
@@ -267,21 +273,21 @@ int
lasso_name_id_management_build_response_msg(LassoNameIdManagement *name_id_management)
{
LassoProfile *profile = NULL;
- gint rc = 0;
+ LassoSamlp2StatusResponse *response;
lasso_bad_param(NAME_ID_MANAGEMENT, name_id_management);
profile = &name_id_management->parent;
/* no response set here means request denied */
- if (! profile->response) {
- profile->response = lasso_samlp2_manage_name_id_response_new();
- lasso_saml20_profile_init_response(profile, LASSO_SAML2_STATUS_CODE_RESPONDER,
+ if (! LASSO_IS_SAMLP2_STATUS_RESPONSE(profile->response)) {
+ response = (LassoSamlp2StatusResponse*)lasso_samlp2_manage_name_id_response_new();
+ lasso_saml20_profile_init_response(profile, response, LASSO_SAML2_STATUS_CODE_RESPONDER,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
+ lasso_release_gobject(response);
}
- rc = lasso_saml20_profile_build_response(profile, "ManageNameIDService", FALSE, profile->http_request_method);
-
- return rc;
+ /* use the same binding as for the request */
+ return lasso_saml20_profile_build_response_msg(profile, "ManageNameIDService", profile->http_request_method, NULL);
}
@@ -308,11 +314,9 @@ lasso_name_id_management_process_response_msg(
lasso_bad_param(NAME_ID_MANAGEMENT, name_id_management);
lasso_null_param(response_msg);
- profile = (LassoProfile*)name_id_management;
+ profile = &name_id_management->parent;
response = (LassoSamlp2StatusResponse*)lasso_samlp2_manage_name_id_response_new();
- rc = lasso_saml20_profile_process_any_response(profile, response, response_msg);
- if (rc)
- goto cleanup;
+ lasso_check_good_rc(lasso_saml20_profile_process_any_response(profile, response, NULL, response_msg));
/* Stop here if signature validation failed. */
goto_cleanup_if_fail_with_rc(profile->signature_status == 0, profile->signature_status);
diff --git a/lasso/saml-2.0/profile.c b/lasso/saml-2.0/profile.c
index 0b10edb0..a2aef281 100644
--- a/lasso/saml-2.0/profile.c
+++ b/lasso/saml-2.0/profile.c
@@ -26,15 +26,17 @@
#include <xmlsec/base64.h>
#include "../utils.h"
-#include "providerprivate.h"
-#include "profileprivate.h"
-#include "profile.h"
+#include "./providerprivate.h"
+#include "./profileprivate.h"
+#include "./profile.h"
+#include "./provider.h"
#include "../id-ff/providerprivate.h"
#include "../id-ff/profile.h"
#include "../id-ff/profileprivate.h"
#include "../id-ff/serverprivate.h"
-#include <../id-ff/sessionprivate.h>
+#include "../id-ff/sessionprivate.h"
+#include "../id-ff/login.h"
#include "../xml/private.h"
#include "../xml/saml-2.0/samlp2_request_abstract.h"
@@ -48,16 +50,23 @@
#include "../debug.h"
static char* lasso_saml20_profile_build_artifact(LassoProvider *provider);
-static int lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, int sign, char **query);
+static int lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char **query,
+ LassoSignatureMethod method, const char *private_key);
static gint lasso_profile_saml20_build_artifact_get_request_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service);
+ const char *service);
static gint lasso_profile_saml20_build_artifact_post_request_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service);
+ const char *service);
static gint lasso_profile_saml20_build_artifact_get_response_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service);
+ const char *service);
static gint lasso_profile_saml20_build_artifact_post_response_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service);
-static gboolean has_signature(LassoNode *node);
+ const char *service);
+static gboolean has_signature(LassoNode *node, LassoSignatureMethod *signature_method, const char
+ **private_key_file);
+
+#define check_msg_body \
+ if (! profile->msg_body) { \
+ return critical_error(LASSO_PROFILE_ERROR_BUILDING_MESSAGE_FAILED); \
+ }
/*
* Helper functions
@@ -84,7 +93,7 @@ cleanup:
}
static char *
-get_url(LassoProvider *provider, char *service, char *binding)
+get_url(LassoProvider *provider, const char *service, const char *binding)
{
char *meta;
char *result;
@@ -96,7 +105,7 @@ get_url(LassoProvider *provider, char *service, char *binding)
}
static char *
-get_response_url(LassoProvider *provider, char *service, char *binding)
+get_response_url(LassoProvider *provider, const char *service, const char *binding)
{
char *meta;
char *result;
@@ -110,6 +119,28 @@ get_response_url(LassoProvider *provider, char *service, char *binding)
return result;
}
+static const char*
+http_method_to_binding(LassoHttpMethod method) {
+ switch (method) {
+ case LASSO_HTTP_METHOD_POST:
+ return "HTTP-POST";
+ case LASSO_HTTP_METHOD_REDIRECT:
+ return "HTTP-Redirect";
+ case LASSO_HTTP_METHOD_SOAP:
+ return "SOAP";
+ case LASSO_HTTP_METHOD_ARTIFACT_GET:
+ case LASSO_HTTP_METHOD_ARTIFACT_POST:
+ return "HTTP-Artifact";
+ case LASSO_HTTP_METHOD_PAOS:
+ return "PAOS";
+ default:
+ return "";
+ }
+}
+
+/*
+ * Artifact Handling functions
+ */
/**
* lasso_saml20_profile_generate_artifact
@@ -125,11 +156,13 @@ char*
lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part)
{
lasso_assign_new_string(profile->private_data->artifact,
- lasso_saml20_profile_build_artifact(LASSO_PROVIDER(profile->server)));
+ lasso_saml20_profile_build_artifact(&profile->server->parent));
if (part == 0) {
- lasso_assign_new_string(profile->private_data->artifact_message, lasso_node_dump(profile->request));
+ lasso_assign_new_string(profile->private_data->artifact_message,
+ lasso_node_dump(profile->request));
} else if (part == 1) {
- lasso_assign_new_string(profile->private_data->artifact_message, lasso_node_dump(profile->response));
+ lasso_assign_new_string(profile->private_data->artifact_message,
+ lasso_node_dump(profile->response));
} else {
/* XXX: RequestDenied here? */
}
@@ -162,44 +195,71 @@ lasso_saml20_profile_build_artifact(LassoProvider *provider)
return ret;
}
-int
-lasso_saml20_profile_set_response_status(LassoProfile *profile,
- const char *code1, const char *code2)
+/*
+ * this function factorize all case for producing SAML artifact messages
+ */
+static gint
+lasso_profile_saml20_build_artifact_msg(LassoProfile *profile,
+ const char *url, int request_or_response, int get_or_post)
{
- LassoSamlp2StatusResponse *status_response = NULL;
- LassoSamlp2Status *status = NULL;
- LassoSamlp2StatusCode *status_code1 = NULL;
- LassoSamlp2StatusCode *status_code2 = NULL;
- int rc = 0;
-
- lasso_bad_param(PROFILE, profile);
- lasso_null_param(code1);
- lasso_extract_node_or_fail(status_response, profile->response, SAMLP2_STATUS_RESPONSE,
- LASSO_PROFILE_ERROR_MISSING_RESPONSE);
+ char *artifact = lasso_saml20_profile_generate_artifact(profile, request_or_response);
- if (! LASSO_IS_SAMLP2_STATUS(status_response->Status)) {
- lasso_assign_new_gobject(status_response->Status,
- (LassoSamlp2Status*)lasso_samlp2_status_new());
+ if (artifact == NULL) {
+ return critical_error(LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
}
- status = status_response->Status;
- if (! LASSO_IS_SAMLP2_STATUS_CODE(status->StatusCode)) {
- lasso_assign_new_gobject(status->StatusCode,
- (LassoSamlp2StatusCode*)lasso_samlp2_status_code_new());
+ /* hack... */
+ if (LASSO_IS_LOGIN(profile)) {
+ LassoLogin *login = (LassoLogin*)profile;
+ lasso_assign_string(login->assertionArtifact, artifact);
}
- status_code1 = status->StatusCode;
- lasso_assign_string(status_code1->Value, code1);
- if (code2) {
- if (! LASSO_IS_SAMLP2_STATUS_CODE(status_code1->StatusCode)) {
- lasso_assign_new_gobject(status_code1->StatusCode,
- (LassoSamlp2StatusCode*)lasso_samlp2_status_code_new());
+ if (get_or_post == 0) {
+ char *query;
+ if (profile->msg_relayState) {
+ query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, "RelayState",
+ profile->msg_relayState, NULL);
+ } else {
+ query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, NULL);
}
- status_code2 = status_code1->StatusCode;
- lasso_assign_string(status_code2->Value, code2);
+ lasso_assign_new_string(profile->msg_url,
+ lasso_concat_url_query(url, query));
+ lasso_release_string(query);
+ } else {
+ lasso_assign_string(profile->msg_url, url);
+ lasso_assign_string(profile->msg_body, artifact);
}
+ return 0;
+}
-cleanup:
- return rc;
+enum {
+ REQUEST = 0,
+ RESPONSE = 1,
+ GET = 0,
+ POST = 1
+};
+
+static gint
+lasso_profile_saml20_build_artifact_get_request_msg(LassoProfile *profile, const char *url)
+{
+ return lasso_profile_saml20_build_artifact_msg(profile, url, REQUEST, GET);
+}
+
+static gint
+lasso_profile_saml20_build_artifact_post_request_msg(LassoProfile *profile, const char *url)
+{
+ return lasso_profile_saml20_build_artifact_msg(profile, url, REQUEST, POST);
+}
+
+static gint
+lasso_profile_saml20_build_artifact_get_response_msg(LassoProfile *profile, const char *url)
+{
+ return lasso_profile_saml20_build_artifact_msg(profile, url, RESPONSE, GET);
+}
+
+static gint
+lasso_profile_saml20_build_artifact_post_response_msg(LassoProfile *profile, const char *url)
+{
+ return lasso_profile_saml20_build_artifact_msg(profile, url, RESPONSE, POST);
}
int
@@ -337,26 +397,24 @@ cleanup:
int
lasso_saml20_profile_process_artifact_response(LassoProfile *profile, const char *msg)
{
- LassoNode *response;
LassoSamlp2ArtifactResponse *artifact_response;
+ int rc = 0;
- /* XXX: handle errors properly */
-
- response = lasso_node_new_from_soap(msg);
- if (!LASSO_IS_SAMLP2_ARTIFACT_RESPONSE(response)) {
- lasso_assign_new_gobject(profile->response, lasso_samlp2_response_new());
- return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
- }
- artifact_response = LASSO_SAMLP2_ARTIFACT_RESPONSE(response);
-
+ artifact_response = (LassoSamlp2ArtifactResponse*)lasso_samlp2_artifact_response_new();
+ lasso_check_good_rc(lasso_saml20_profile_process_any_response(profile,
+ &artifact_response->parent, NULL, msg));
+ /* XXX: check signature status */
+ goto_cleanup_if_fail_with_rc(profile->response != NULL,
+ critical_error(LASSO_PROFILE_ERROR_INVALID_RESPONSE));
if (artifact_response->any == NULL) {
- lasso_assign_new_gobject(profile->response, lasso_samlp2_response_new());
- return LASSO_PROFILE_ERROR_MISSING_RESPONSE;
+ lasso_release_gobject(profile->response);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_ARTIFACT);
}
lasso_assign_gobject(profile->response, artifact_response->any);
- lasso_release_gobject(response);
- return 0;
+cleanup:
+ lasso_release_gobject(artifact_response);
+ return rc;
}
/**
@@ -384,7 +442,6 @@ lasso_profile_is_saml_query(const gchar *query)
return FALSE;
}
-
static void
lasso_saml20_profile_set_session_from_dump_decrypt(
LassoSaml2Assertion *assertion, G_GNUC_UNUSED gpointer data)
@@ -423,7 +480,8 @@ lasso_saml20_profile_set_session_from_dump(LassoProfile *profile)
* lasso_saml20_profile_process_name_identifier_decryption:
* @profile: the #LassoProfile object
* @name_id: the field containing the #LassoSaml2NameID object
- * @encrypted_id: the field containing an encrypted #LassoSaml2NameID as a #LassoSaml2EncryptedElement
+ * @encrypted_id: the field containing an encrypted #LassoSaml2NameID as a
+ * #LassoSaml2EncryptedElement
*
* Place content of the NameID in the profile nameIdentifier field, if no NameID is present but an
* EncryptedElement is, then decrypt it, store it in place of the name_id field and in the
@@ -473,6 +531,10 @@ cleanup:
return rc;
}
+/*
+ * Request handling functions
+ */
+
/**
* lasso_saml20_profile_process_any_request:
* @profile: a #LassoProfile object
@@ -493,7 +555,7 @@ cleanup:
int
lasso_saml20_profile_process_any_request(LassoProfile *profile,
LassoNode *request_node,
- char *request_msg)
+ const char *request_msg)
{
int rc = 0;
LassoSaml2NameID *name_id = NULL;
@@ -562,7 +624,7 @@ cleanup:
int
lasso_saml20_profile_process_soap_request(LassoProfile *profile,
- char *request_msg)
+ const char *request_msg)
{
int rc = 0;
LassoSaml2NameID *issuer = NULL;
@@ -592,7 +654,7 @@ cleanup:
int
lasso_saml20_init_request(LassoProfile *profile,
- char *remote_provider_id,
+ const char *remote_provider_id,
gboolean first_in_session,
LassoSamlp2RequestAbstract *request_abstract,
LassoHttpMethod http_method,
@@ -677,154 +739,184 @@ lasso_saml20_init_request(LassoProfile *profile,
lasso_assign_new_string(request_abstract->IssueInstant, lasso_get_current_time());
lasso_assign_gobject(profile->request, LASSO_NODE(request_abstract));
+ /* set signature */
+ lasso_check_good_rc(lasso_profile_saml20_setup_message_signature(profile, profile->request));
+
cleanup:
return rc;
}
static int
-lasso_saml20_profile_build_post_request_msg(LassoProfile *profile,
- LassoProvider *provider, char *service)
+lasso_saml20_profile_build_redirect_request_msg(LassoProfile *profile, const char *url)
{
- int rc = 0;
- LassoSamlp2RequestAbstract *request_abstract;
-
- lasso_bad_param(PROFILE, profile);
- lasso_bad_param(PROVIDER, provider);
- lasso_extract_node_or_fail(request_abstract, profile->request, SAMLP2_REQUEST_ABSTRACT,
- LASSO_PROFILE_ERROR_BUILDING_MESSAGE_FAILED);
+ return lasso_saml20_profile_build_http_redirect(profile,
+ profile->request,
+ url);
+}
- lasso_assign_new_string(profile->msg_url, get_response_url(provider, service, "HTTP-POST"));
- if (! profile->msg_url) {
- return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
- }
+static int
+lasso_saml20_profile_build_post_request_msg(LassoProfile *profile,
+ const char *url)
+{
+ lasso_assign_string(profile->msg_url, url);
lasso_assign_new_string(profile->msg_body,
- lasso_node_export_to_base64(LASSO_NODE(request_abstract)));
- if (! profile->msg_body) {
- return critical_error(LASSO_PROFILE_ERROR_BUILDING_MESSAGE_FAILED);
- }
-cleanup:
- return rc;
+ lasso_node_export_to_base64(profile->request));
+ check_msg_body;
+ return 0;
}
static int
-lasso_saml20_profile_build_soap_request_msg(LassoProfile *profile, LassoProvider *provider,
- char *service)
+lasso_saml20_profile_build_soap_request_msg(LassoProfile *profile, const char *url)
{
- int rc = 0;
- char *url = NULL;
- LassoSamlp2RequestAbstract *request_abstract;
-
- lasso_bad_param(PROFILE, profile);
- lasso_bad_param(PROVIDER, provider);
- lasso_extract_node_or_fail(request_abstract, profile->request, SAMLP2_REQUEST_ABSTRACT,
- LASSO_PROFILE_ERROR_BUILDING_MESSAGE_FAILED);
-
- url = get_url(provider, service, "SOAP");
- if (! url) {
- rc = critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
- goto cleanup;
- }
+ lasso_assign_string(profile->msg_url, url);
lasso_assign_new_string(profile->msg_body,
- lasso_node_export_to_soap(LASSO_NODE(request_abstract)));
- lasso_transfer_string(profile->msg_url, url);
-
- if (! profile->msg_body) {
- return LASSO_PROFILE_ERROR_BUILDING_MESSAGE_FAILED;
- }
-
-cleanup:
- lasso_release_string(url);
- return rc;
+ lasso_node_export_to_soap(profile->request));
+ check_msg_body;
+ return 0;
}
+/**
+ * the url parameters is special for this function, it does not give the destination of the message
+ * (it's implicit for the caller of this function) but where response should be posted later) */
static int
-lasso_saml20_profile_build_redirect_request_msg(LassoProfile *profile, LassoProvider *provider,
- char *service)
+lasso_profile_saml20_build_paos_request_msg(LassoProfile *profile, const char *url)
{
- int rc = 0;
- char *url = NULL;
-
- url = get_url(provider, service, "HTTP-Redirect");
- rc = lasso_saml20_profile_build_http_redirect(profile,
- profile->request,
- url);
-
-cleanup:
- lasso_release_string(url);
- return rc;
-
+ lasso_assign_new_string(profile->msg_body,
+ lasso_node_export_to_paos_request(profile->request,
+ profile->server->parent.ProviderID, url,
+ profile->msg_relayState));
+ check_msg_body;
+ return 0;
}
int
-lasso_saml20_profile_build_request_msg(LassoProfile *profile, char *service)
+lasso_saml20_profile_build_request_msg(LassoProfile *profile, const char *service,
+ LassoHttpMethod method, const char *_url)
{
LassoProvider *provider;
+ char *made_url = NULL, *url;
int rc = 0;
lasso_bad_param(PROFILE, profile);
lasso_profile_clean_msg_info(profile);
lasso_check_good_rc(get_provider(profile, &provider));
+ url = (char*)_url;
+
+ /* check presence of a request */
+ if (! LASSO_IS_SAMLP2_REQUEST_ABSTRACT(profile->request)) {
+ return critical_error(LASSO_PROFILE_ERROR_MISSING_REQUEST);
+ }
- switch (profile->http_request_method) {
+ /* if not explicitely given, automatically determine an URI from the metadatas */
+ if (url == NULL) {
+ made_url = url = get_url(provider, service, http_method_to_binding(method));
+ }
+
+ switch (method) {
case LASSO_HTTP_METHOD_SOAP:
- rc = lasso_saml20_profile_build_soap_request_msg(profile, provider,
- service);
+ rc = lasso_saml20_profile_build_soap_request_msg(profile, url);
break;
case LASSO_HTTP_METHOD_POST:
- rc = lasso_saml20_profile_build_post_request_msg(profile, provider,
- service);
+ rc = lasso_saml20_profile_build_post_request_msg(profile, url);
break;
case LASSO_HTTP_METHOD_REDIRECT:
- rc = lasso_saml20_profile_build_redirect_request_msg(profile, provider,
- service);
+ rc = lasso_saml20_profile_build_redirect_request_msg(profile, url);
break;
case LASSO_HTTP_METHOD_ARTIFACT_GET:
- rc = lasso_profile_saml20_build_artifact_get_request_msg(profile, provider,
- service);
+ rc = lasso_profile_saml20_build_artifact_get_request_msg(profile, url);
break;
- case LASSO_HTTP_METHOD_ARTIFACT_GET:
- rc = lasso_profile_saml20_build_artifact_post_request_msg(profile, provider,
- service);
+ case LASSO_HTTP_METHOD_ARTIFACT_POST:
+ rc = lasso_profile_saml20_build_artifact_post_request_msg(profile, url);
break;
+ case LASSO_HTTP_METHOD_PAOS:
+ rc = lasso_profile_saml20_build_paos_request_msg(profile, url);
default:
rc = LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD;
break;
}
cleanup:
+ lasso_release_string(made_url);
return rc;
}
+/*
+ * Response handling functions
+ */
+
int
-lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_code1, const char *status_code2)
+lasso_saml20_profile_set_response_status(LassoProfile *profile,
+ const char *code1, const char *code2)
{
LassoSamlp2StatusResponse *status_response = NULL;
- LassoSamlp2RequestAbstract *request_abstract = NULL;
- LassoServer *server = NULL;
+ LassoSamlp2Status *status = NULL;
+ LassoSamlp2StatusCode *status_code1 = NULL;
+ LassoSamlp2StatusCode *status_code2 = NULL;
int rc = 0;
lasso_bad_param(PROFILE, profile);
+ lasso_null_param(code1);
lasso_extract_node_or_fail(status_response, profile->response, SAMLP2_STATUS_RESPONSE,
LASSO_PROFILE_ERROR_MISSING_RESPONSE);
- lasso_extract_node_or_fail(server, profile->server, SERVER,
- LASSO_PROFILE_ERROR_MISSING_SERVER);
- lasso_extract_node_or_fail(request_abstract, profile->request, SAMLP2_REQUEST_ABSTRACT,
- LASSO_PROFILE_ERROR_MISSING_REQUEST);
+
+ if (! LASSO_IS_SAMLP2_STATUS(status_response->Status)) {
+ lasso_assign_new_gobject(status_response->Status,
+ (LassoSamlp2Status*)lasso_samlp2_status_new());
+ }
+ status = status_response->Status;
+ if (! LASSO_IS_SAMLP2_STATUS_CODE(status->StatusCode)) {
+ lasso_assign_new_gobject(status->StatusCode,
+ (LassoSamlp2StatusCode*)lasso_samlp2_status_code_new());
+ }
+ status_code1 = status->StatusCode;
+ lasso_assign_string(status_code1->Value, code1);
+
+ if (code2) {
+ if (! LASSO_IS_SAMLP2_STATUS_CODE(status_code1->StatusCode)) {
+ lasso_assign_new_gobject(status_code1->StatusCode,
+ (LassoSamlp2StatusCode*)lasso_samlp2_status_code_new());
+ }
+ status_code2 = status_code1->StatusCode;
+ lasso_assign_string(status_code2->Value, code2);
+ }
+
+cleanup:
+ return rc;
+}
+
+
+int
+lasso_saml20_profile_init_response(LassoProfile *profile, LassoSamlp2StatusResponse *status_response,
+ const char *status_code1, const char *status_code2)
+{
+ LassoSamlp2RequestAbstract *request_abstract = NULL;
+ int rc = 0;
+
+ lasso_bad_param(PROFILE, profile);
+ if (! LASSO_IS_SAMLP2_STATUS_RESPONSE(status_response))
+ return LASSO_PROFILE_ERROR_MISSING_RESPONSE;
+ lasso_assign_gobject(profile->response, status_response);
lasso_assign_new_string(status_response->ID, lasso_build_unique_id(32));
lasso_assign_string(status_response->Version, "2.0");
- lasso_assign_new_gobject(status_response->Issuer,
- LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
- server->parent.ProviderID)));
+ if (LASSO_IS_SERVER(profile->server)) {
+ lasso_assign_new_gobject(status_response->Issuer,
+ LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
+ profile->server->parent.ProviderID)));
+ }
lasso_assign_new_string(status_response->IssueInstant, lasso_get_current_time());
- lasso_assign_string(status_response->InResponseTo, request_abstract->ID);
+ if (LASSO_IS_SAMLP2_REQUEST_ABSTRACT(profile->request)) {
+ lasso_assign_string(status_response->InResponseTo,
+ ((LassoSamlp2RequestAbstract*)request_abstract)->ID);
+ }
lasso_check_good_rc(lasso_profile_saml20_setup_message_signature(profile,
profile->response));
- if (status_code1)
+ if (status_code1) {
lasso_saml20_profile_set_response_status(profile,
status_code1, status_code2);
+ }
cleanup:
return rc;
@@ -860,8 +952,8 @@ lasso_saml20_profile_validate_request(LassoProfile *profile, gboolean needs_iden
goto cleanup;
/* init the response */
- lasso_assign_gobject(profile->response, &status_response->parent);
- lasso_saml20_profile_init_response(profile, LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
+ lasso_saml20_profile_init_response(profile, status_response,
+ LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
if (profile->signature_status) {
message(G_LOG_LEVEL_WARNING, "Request signature is invalid");
@@ -878,59 +970,6 @@ cleanup:
}
-static int
-lasso_saml20_profile_build_post_response(LassoProfile *profile, LassoProvider *provider, char *service)
-{
- lasso_bad_param(PROFILE, profile);
- lasso_bad_param(PROVIDER, provider);
-
- lasso_assign_new_string(profile->msg_url, get_response_url(provider, service, "HTTP-POST"));
- if (! profile->msg_url) {
- return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
- }
- lasso_assign_new_string(profile->msg_body, lasso_node_export_to_base64(profile->request));
- if (! profile->msg_body) {
- return critical_error(LASSO_PROFILE_ERROR_BUILDING_MESSAGE_FAILED);
- }
- return 0;
-}
-
-static int
-lasso_saml20_profile_build_redirect_response(LassoProfile *profile, LassoProvider *provider, char
- *service)
-{
- LassoSamlp2StatusResponse *status_response = NULL;
- char *url = NULL;
- int rc = 0;
-
- lasso_null_param(service);
-
- url = get_response_url(provider, service, "HTTP-Redirect");
- rc = lasso_saml20_profile_build_http_redirect(profile,
- profile->response,
- lasso_flag_add_signature,
- url);
-
-cleanup:
- lasso_release_string(url);
- return rc;
-}
-
-static int
-lasso_saml20_profile_build_soap_response(LassoProfile *profile)
-{
- lasso_bad_param(PROFILE, profile);
-
- lasso_release_string(profile->msg_url);
- lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->response));
-
- if (! profile->msg_body) {
- return LASSO_PROFILE_ERROR_BUILDING_RESPONSE_FAILED;
- }
-
- return 0;
-}
-
/**
* lasso_saml20_profile_export_to_query:
* @profile: a #LassoProfile
@@ -938,41 +977,35 @@ lasso_saml20_profile_build_soap_response(LassoProfile *profile)
* @sign: TRUE if query must signed, FALSE otherwise
*
* Create a query following the DEFLATE encoding of the SAML 2.0 HTTP
- * Redirect binding.
+ * Redirect binding. If the root message node has an XML signature, signature is removed and query
+ * is signed.
*
- * Return value: a newly allocated string containing the query string if successfull, NULL otherwise.
+ * Return value: a newly allocated string containing the query string if successfull, NULL
+ * otherwise.
*/
static int
-lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, int sign, char **query) {
+lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, char **query,
+ LassoSignatureMethod signature_method, const char *private_key_file) {
char *unsigned_query = NULL;
char *result = NULL;
int rc = 0;
- lasso_bad_param(PROFILE, profile);
- lasso_bad_param(NODE, msg);
-
unsigned_query = lasso_node_build_query(msg);
goto_cleanup_if_fail_with_rc(unsigned_query != NULL,
LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
if (profile->msg_relayState) {
- unsigned_query = lasso_url_add_parameters(unsigned_query, 1, "RelayState", profile->msg_relayState, NULL);
+ unsigned_query = lasso_url_add_parameters(unsigned_query, 1, "RelayState",
+ profile->msg_relayState, NULL);
if (strlen(profile->msg_relayState) > 80) {
- g_warning("Encoded a RelayState of more than 80 bytes, see #3.4.3 of"
- " saml-bindings-2.0-os");
+ message(G_LOG_LEVEL_WARNING, "Encoded a RelayState of more than 80 bytes, "
+ "see #3.4.3 of saml-bindings-2.0-os");
}
}
- if (sign && lasso_flag_add_signature) {
- LassoServer *server = profile->server;
- goto_cleanup_if_fail_with_rc (LASSO_IS_SERVER(server),
- LASSO_PROFILE_ERROR_MISSING_SERVER);
- goto_cleanup_if_fail_with_rc (
- profile->server->signature_method != LASSO_SIGNATURE_TYPE_NONE &&
- profile->server->private_key,
- LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED);
- result = lasso_query_sign(unsigned_query, profile->server->signature_method,
- profile->server->private_key);
- goto_cleanup_if_fail_with_rc(result != NULL, LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
+ if (signature_method && private_key_file && lasso_flag_add_signature) {
+ result = lasso_query_sign(unsigned_query, signature_method, private_key_file);
+ goto_cleanup_if_fail_with_rc(result != NULL,
+ LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
lasso_transfer_string(*query, result);
} else {
lasso_transfer_string(*query, unsigned_query);
@@ -983,37 +1016,24 @@ cleanup:
return rc;
}
-static void
-remove_signature(LassoNode *node) {
- LassoNodeClass *klass;
-
- if (node == NULL)
- return;
-
- klass = LASSO_NODE_GET_CLASS(node);
- /* follow the class parenting chain */
- while (klass && LASSO_IS_NODE_CLASS(klass)) {
- if (klass && klass->node_data && klass->node_data->sign_type_offset != 0) {
- G_STRUCT_MEMBER(LassoSignatureType, node, klass->node_data->sign_type_offset) =
- LASSO_SIGNATURE_TYPE_NONE;
- }
- klass = g_type_class_peek_parent(klass);
- }
-}
-
static gboolean
-has_signature(LassoNode *node) {
+has_signature(LassoNode *node, LassoSignatureMethod *method, const char **private_key_file) {
LassoNodeClass *klass;
if (node == NULL)
- return;
+ return FALSE;
klass = LASSO_NODE_GET_CLASS(node);
/* follow the class parenting chain */
while (klass && LASSO_IS_NODE_CLASS(klass)) {
if (klass && klass->node_data && klass->node_data->sign_type_offset != 0) {
- if (G_STRUCT_MEMBER(LassoSignatureType, node, klass->node_data->sign_type_offset) !=
- LASSO_SIGNATURE_TYPE_NONE) {
+ if (G_STRUCT_MEMBER(LassoSignatureType, node,
+ klass->node_data->sign_type_offset)
+ != LASSO_SIGNATURE_TYPE_NONE) {
+ *method = G_STRUCT_MEMBER(LassoSignatureMethod, node,
+ klass->node_data->sign_method_offset);
+ *private_key_file = G_STRUCT_MEMBER(char*, node,
+ klass->node_data->private_key_file_offset);
return TRUE;
}
}
@@ -1042,54 +1062,102 @@ lasso_saml20_profile_build_http_redirect(LassoProfile *profile,
char *query = NULL;
int rc = 0;
gboolean must_sign = FALSE;
+ LassoSignatureMethod signature_method = 0;
+ const char *private_key_file = NULL;
- if (url == NULL) {
- return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
- }
+ goto_cleanup_if_fail_with_rc (url != NULL, LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
/* if message is signed, remove XML signature, add query signature */
- if (has_signature(msg)) {
+ if (has_signature(msg, &signature_method, (const char **)&private_key_file)) {
must_sign = TRUE;
- remove_signature(msg);
+ lasso_node_remove_signature(msg);
}
- /* No signature on the XML message */
- rc = lasso_saml20_profile_export_to_query(profile, msg, must_sign, &query);
- if (rc)
- return rc;
+ lasso_check_good_rc(lasso_saml20_profile_export_to_query(profile, msg, &query,
+ signature_method, private_key_file));
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
lasso_release(profile->msg_body);
lasso_release(query);
+cleanup:
+ return rc;
+}
+
+static int
+lasso_saml20_profile_build_redirect_response_msg(LassoProfile *profile, const char *url)
+{
+ return lasso_saml20_profile_build_http_redirect(profile,
+ profile->response,
+ url);
+}
+
+static int
+lasso_saml20_profile_build_post_response_msg(LassoProfile *profile, const char *url)
+{
+ lasso_assign_string(profile->msg_url, url);
+ lasso_assign_new_string(profile->msg_body, lasso_node_export_to_base64(profile->request));
+ check_msg_body;
+ return 0;
+}
+
+static int
+lasso_saml20_profile_build_soap_response_msg(LassoProfile *profile)
+{
+ lasso_release_string(profile->msg_url);
+ lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->response));
+ check_msg_body;
return 0;
}
+
int
-lasso_saml20_profile_build_response_msg(LassoProfile *profile, char *service, LassoHttpMethod method)
+lasso_saml20_profile_build_response_msg(LassoProfile *profile, char *service,
+ LassoHttpMethod method, const char *_url)
{
LassoProvider *provider;
+ char *made_url = NULL, *url;
int rc = 0;
lasso_bad_param(PROFILE, profile);
lasso_profile_clean_msg_info(profile);
lasso_check_good_rc(get_provider(profile, &provider));
+ url = (char*)_url;
+
+ /* check presence of a request */
+ if (! LASSO_IS_SAMLP2_STATUS_RESPONSE(profile->response)) {
+ return critical_error(LASSO_PROFILE_ERROR_MISSING_RESPONSE);
+ }
+
+ /* if not explicitely given, automatically determine an URI from the metadatas */
+ if (url == NULL && service) {
+ made_url = url = get_response_url(provider, service, http_method_to_binding(method));
+ }
switch (method) {
case LASSO_HTTP_METHOD_POST:
- rc = lasso_saml20_profile_build_post_response(profile, provider, service);
+ case LASSO_HTTP_METHOD_REDIRECT:
+ case LASSO_HTTP_METHOD_ARTIFACT_GET:
+ case LASSO_HTTP_METHOD_ARTIFACT_POST:
+ goto_cleanup_with_rc(critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL));
+ default:
+ break;
+ }
+
+ switch (method) {
+ case LASSO_HTTP_METHOD_POST:
+ rc = lasso_saml20_profile_build_post_response_msg(profile, url);
break;
case LASSO_HTTP_METHOD_REDIRECT:
- rc = lasso_saml20_profile_build_redirect_response(profile, provider,
- service);
+ rc = lasso_saml20_profile_build_redirect_response_msg(profile, url);
break;
case LASSO_HTTP_METHOD_SOAP:
- rc = lasso_saml20_profile_build_soap_response(profile);
+ rc = lasso_saml20_profile_build_soap_response_msg(profile);
break;
case LASSO_HTTP_METHOD_ARTIFACT_GET:
- rc = lasso_profile_saml20_build_artifact_get_response_msg(profile, provider, service);
+ rc = lasso_profile_saml20_build_artifact_get_response_msg(profile, url);
break;
- case LASSO_HTTP_METHOD_ARTIFACT_GET:
- rc = lasso_profile_saml20_build_artifact_post_response_msg(profile, provider, service);
+ case LASSO_HTTP_METHOD_ARTIFACT_POST:
+ rc = lasso_profile_saml20_build_artifact_post_response_msg(profile, url);
break;
default:
rc= LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE;
@@ -1097,6 +1165,7 @@ lasso_saml20_profile_build_response_msg(LassoProfile *profile, char *service, La
}
cleanup:
+ lasso_release_string(made_url);
return rc;
}
@@ -1118,7 +1187,8 @@ cleanup:
int
lasso_saml20_profile_process_any_response(LassoProfile *profile,
LassoSamlp2StatusResponse *status_response,
- char *response_msg)
+ LassoHttpMethod *response_method,
+ const char *response_msg)
{
int rc = 0;
@@ -1128,7 +1198,6 @@ lasso_saml20_profile_process_any_response(LassoProfile *profile,
LassoSamlp2StatusResponse *response_abstract = NULL;
LassoSamlp2Status *status = NULL;
LassoSamlp2StatusCode *status_code1 = NULL;
- LassoSamlp2StatusCode *status_code2 = NULL;
LassoMessageFormat format;
xmlDoc *doc = NULL;
@@ -1145,6 +1214,21 @@ lasso_saml20_profile_process_any_response(LassoProfile *profile,
rc = LASSO_PROFILE_ERROR_INVALID_MSG;
goto cleanup;
}
+ if (response_method) {
+ switch (format) {
+ case LASSO_MESSAGE_FORMAT_SOAP:
+ *response_method = LASSO_HTTP_METHOD_SOAP;
+ break;
+ case LASSO_MESSAGE_FORMAT_QUERY:
+ *response_method = LASSO_HTTP_METHOD_REDIRECT;
+ break;
+ case LASSO_MESSAGE_FORMAT_BASE64:
+ *response_method = LASSO_HTTP_METHOD_POST;
+ break;
+ default:
+ return LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE;
+ }
+ }
lasso_assign_gobject(profile->response, (LassoNode*)status_response);
lasso_extract_node_or_fail(response_abstract, profile->response, SAMLP2_STATUS_RESPONSE,
LASSO_PROFILE_ERROR_INVALID_MSG);
@@ -1195,7 +1279,7 @@ cleanup:
*/
int
lasso_saml20_profile_process_soap_response(LassoProfile *profile,
- char *response_msg)
+ const char *response_msg)
{
int rc = 0;
LassoSaml2NameID *issuer = NULL;
@@ -1269,11 +1353,20 @@ lasso_profile_saml20_setup_message_signature(LassoProfile *profile, LassoNode *r
{
lasso_bad_param(PROFILE, profile);
- if (! lasso_flag_sign_messages) {
- message(G_LOG_LEVEL_WARNING, "message should be signed but no-sign-messages flag is " \
- "activated, so it won't be");
- return 0;
+ switch (lasso_profile_get_signature_hint(profile)) {
+ case LASSO_PROFILE_SIGNATURE_HINT_MAYBE:
+ if (! lasso_flag_sign_messages) {
+ message(G_LOG_LEVEL_WARNING, "message should be signed but no-sign-messages flag is " \
+ "activated, so it won't be");
+ return 0;
+ }
+ break;
+ case LASSO_PROFILE_SIGNATURE_HINT_FORBID:
+ return 0;
+ default:
+ break;
}
+
if (! LASSO_IS_SERVER(profile->server)) {
return LASSO_PROFILE_ERROR_MISSING_SERVER;
}
@@ -1314,63 +1407,22 @@ lasso_profile_saml20_setup_message_signature(LassoProfile *profile, LassoNode *r
return 0;
}
-/*
- * this function factorize all case for producing SAML artifact messages
- */
-static gint
-lasso_profile_saml20_build_artifact_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service, int request_or_response, int get_or_post)
+gint
+lasso_saml20_profile_setup_encrypted_node(LassoProvider *provider,
+ LassoNode **node_to_encrypt, LassoNode **node_destination)
{
- char *artifact = lasso_saml20_profile_generate_artifact(profile, request_or_response);
- if (request_or_response == 0) {
- url = get_url(provider, service, "HTTP-Artifact");
- } else {
- url = get_response_url(provider, service, "HTTP-Artifact");
+ LassoNode *encrypted_node;
+
+ if (! LASSO_IS_PROVIDER(provider)) {
+ return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
- if (! url) {
- return LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL;
+ encrypted_node = (LassoNode*)lasso_node_encrypt(*node_to_encrypt,
+ lasso_provider_get_encryption_public_key(provider),
+ lasso_provider_get_encryption_sym_key_type(provider));
+ if (! encrypted_node) {
+ return LASSO_DS_ERROR_ENCRYPTION_FAILED;
}
- if (get_or_post == 0) {
- if (profile->msg_relayState) {
- query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, "RelayState",
- profile->msg_relayState, NULL);
- } else {
- query = lasso_url_add_parameters(NULL, 0, "SAMLart", artifact, NULL);
- }
- lasso_assign_new_string(profile->msg_url,
- lasso_concat_url_query(url, query));
- lasso_release_string(query);
- lasso_release_string(url);
- } else {
- lasso_assign_new_string(profile->msg_url, url);
- lasso_assign_string(profile->msg_body, artifact);
- }
-}
-
-static gint
-lasso_profile_saml20_build_artifact_get_request_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service)
-{
- return lasso_profile_saml20_build_artifact_msg(profile, provider, service, 0, 0);
-}
-
-static gint
-lasso_profile_saml20_build_artifact_post_request_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service)
-{
- return lasso_profile_saml20_build_artifact_msg(profile, provider, service, 0, 1);
-}
-
-static gint
-lasso_profile_saml20_build_artifact_get_response_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service)
-{
- return lasso_profile_saml20_build_artifact_msg(profile, provider, service, 1, 0);
-}
-
-static gint
-lasso_profile_saml20_build_artifact_post_response_msg(LassoProfile *profile,
- LassoProvider *provider, const char *service)
-{
- return lasso_profile_saml20_build_artifact_msg(profile, provider, service, 1, 1);
+ lasso_assign_new_gobject(*node_destination, encrypted_node);
+ lasso_release_gobject(*node_to_encrypt);
+ return 0;
}
diff --git a/lasso/saml-2.0/profileprivate.h b/lasso/saml-2.0/profileprivate.h
index 9fb8cc63..6efc7f4d 100644
--- a/lasso/saml-2.0/profileprivate.h
+++ b/lasso/saml-2.0/profileprivate.h
@@ -36,7 +36,7 @@ extern "C" {
#include "../xml/saml-2.0/samlp2_request_abstract.h"
#include "../id-ff/provider.h"
-int lasso_saml20_init_request(LassoProfile *profile, char *remote_provider_id,
+int lasso_saml20_init_request(LassoProfile *profile, const char *remote_provider_id,
gboolean first_in_session, LassoSamlp2RequestAbstract *request_abstract,
LassoHttpMethod http_method, LassoMdProtocolType protocol_type);
char* lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part);
@@ -57,23 +57,26 @@ int lasso_saml20_profile_process_artifact_response(LassoProfile *profile, const
gint lasso_saml20_profile_set_session_from_dump(LassoProfile *profile);
gint lasso_saml20_profile_process_name_identifier_decryption(LassoProfile *profile,
LassoSaml2NameID **name_id, LassoSaml2EncryptedElement **encrypted_id);
-int lasso_saml20_profile_process_soap_request(LassoProfile *profile, char *request_msg);
-int lasso_saml20_profile_process_soap_response(LassoProfile *profile, char *response_msg);
+int lasso_saml20_profile_process_soap_request(LassoProfile *profile, const char *request_msg);
+int lasso_saml20_profile_process_soap_response(LassoProfile *profile, const char *response_msg);
int lasso_saml20_profile_process_any_request(LassoProfile *profile, LassoNode *request_node,
- char *request_msg);
-int lasso_saml20_profile_process_any_response(LassoProfile *profile, LassoSamlp2StatusResponse *response_node, char *response_msg);
+ const char *request_msg);
+int lasso_saml20_profile_process_any_response(LassoProfile *profile, LassoSamlp2StatusResponse *response_node, LassoHttpMethod *response_method, const char *response_msg);
int lasso_saml20_profile_setup_request_signing(LassoProfile *profile);
-int lasso_saml20_profile_build_request_msg(LassoProfile *profile, char *service, gboolean no_signature);
-int lasso_saml20_profile_build_response(LassoProfile *profile, char *service, gboolean no_signature, LassoHttpMethod method);
-int lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_code1,
- const char *status_code2);
+int lasso_saml20_profile_build_request_msg(LassoProfile *profile, const char *service, LassoHttpMethod method, const char *url);
+int lasso_saml20_profile_build_response_msg(LassoProfile *profile, char *service,
+ LassoHttpMethod method, const char *_url);
+int lasso_saml20_profile_init_response(LassoProfile *profile,
+ LassoSamlp2StatusResponse *status_response, const char *status_code1, const char *status_code2);
int lasso_saml20_profile_validate_request(LassoProfile *profile, gboolean needs_identity, LassoSamlp2StatusResponse *status_response, LassoProvider **provider_out);
gint lasso_saml20_build_http_redirect_query_simple(LassoProfile *profile, LassoNode *msg,
- gboolean must_sign, const char *profile_name, gboolean is_response);
+ const char *profile_name, gboolean is_response);
gint lasso_saml20_profile_build_http_redirect(LassoProfile *profile, LassoNode *msg,
- gboolean must_sign, const char *url);
+ const char *url);
gint lasso_profile_saml20_setup_message_signature(LassoProfile *profile,
LassoNode *request_or_response);
+gint lasso_saml20_profile_setup_encrypted_node(LassoProvider *provider,
+ LassoNode **node_to_encrypt, LassoNode **node_destination);
#ifdef __cplusplus
}
diff --git a/lasso/saml-2.0/provider.c b/lasso/saml-2.0/provider.c
index 5598fd60..613de792 100644
--- a/lasso/saml-2.0/provider.c
+++ b/lasso/saml-2.0/provider.c
@@ -223,7 +223,7 @@ lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
LassoHttpMethod method = LASSO_HTTP_METHOD_NONE;
int i;
const char *possible_bindings[] = {
- "HTTP-Redirect", "HTTP-Post", "SOAP", NULL
+ "HTTP-Redirect", "HTTP-Post", "SOAP", "HTTP-Artifact", NULL
};
LassoHttpMethod method_bindings[] = {
LASSO_HTTP_METHOD_SOAP, LASSO_HTTP_METHOD_REDIRECT, LASSO_HTTP_METHOD_POST
diff --git a/lasso/saml-2.0/saml2_helper.c b/lasso/saml-2.0/saml2_helper.c
index fe830f25..4b8d5503 100644
--- a/lasso/saml-2.0/saml2_helper.c
+++ b/lasso/saml-2.0/saml2_helper.c
@@ -178,7 +178,7 @@ lasso_saml2_assertion_get_subject_confirmation(LassoSaml2Assertion *saml2_assert
return subject->SubjectConfirmation;
}
-static LassoSaml2SubjectConfirmationData*
+LassoSaml2SubjectConfirmationData*
lasso_saml2_assertion_get_subject_confirmation_data(LassoSaml2Assertion *saml2_assertion, gboolean create)
{
LassoSaml2SubjectConfirmation *subject_confirmation;
@@ -707,5 +707,3 @@ lasso_saml2_assertion_add_attribute_with_node(LassoSaml2Assertion *assertion, co
cleanup:
return rc;
}
-
-
diff --git a/lasso/saml-2.0/saml2_helper.h b/lasso/saml-2.0/saml2_helper.h
index 1b99185a..adeea482 100644
--- a/lasso/saml-2.0/saml2_helper.h
+++ b/lasso/saml-2.0/saml2_helper.h
@@ -57,8 +57,9 @@ LASSO_EXPORT gboolean lasso_saml2_assertion_is_audience_restricted(
LASSO_EXPORT LassoSaml2NameID* lasso_saml2_name_id_build_persistent(const char *id,
const char *idpID, const char *providerID);
-LASSO_EXPORT LassoSaml2EncryptedElement* lasso_saml2_encrypted_element_build_encrypted_persistent_name_id(
- const char *id, const char *idpID, const LassoProvider *provider);
+LASSO_EXPORT LassoSaml2EncryptedElement*
+ lasso_saml2_encrypted_element_build_encrypted_persistent_name_id(const char *id,
+ const char *idpID, const LassoProvider *provider);
LASSO_EXPORT void lasso_saml2_assertion_set_subject_name_id(LassoSaml2Assertion *saml2_assertion,
LassoNode *node);
@@ -88,8 +89,12 @@ LASSO_EXPORT LassoProvider* lasso_saml2_assertion_get_issuer_provider(
LASSO_EXPORT int lasso_server_saml2_assertion_setup_signature(LassoServer *server,
LassoSaml2Assertion *saml2_assertion);
-LASSO_EXPORT int lasso_saml2_assertion_add_attribute_with_node(LassoSaml2Assertion *assertion, const char *name, const char *nameformat, LassoNode *content);
+LASSO_EXPORT int lasso_saml2_assertion_add_attribute_with_node(LassoSaml2Assertion *assertion, const
+ char *name, const char *nameformat, LassoNode *content);
+LASSO_EXPORT LassoSaml2SubjectConfirmationData*
+ lasso_saml2_assertion_get_subject_confirmation_data(LassoSaml2Assertion *saml2_assertion,
+ gboolean create);
#ifdef __cplusplus
}
diff --git a/lasso/xml/saml-2.0/samlp2_request_abstract.c b/lasso/xml/saml-2.0/samlp2_request_abstract.c
index 772b5c91..0c16930c 100644
--- a/lasso/xml/saml-2.0/samlp2_request_abstract.c
+++ b/lasso/xml/saml-2.0/samlp2_request_abstract.c
@@ -170,9 +170,9 @@ class_init(LassoSamlp2RequestAbstractClass *klass)
LassoSamlp2RequestAbstract, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(
LassoSamlp2RequestAbstract, sign_method);
- nclass->node_data->private_key_file_offset = G_STRUCT_OFFSET(LassoSaml2Assertion,
+ nclass->node_data->private_key_file_offset = G_STRUCT_OFFSET(LassoSamlp2RequestAbstract,
private_key_file);
- nclass->node_data->certificate_file_offset = G_STRUCT_OFFSET(LassoSaml2Assertion,
+ nclass->node_data->certificate_file_offset = G_STRUCT_OFFSET(LassoSamlp2RequestAbstract,
certificate_file);
}
diff --git a/lasso/xml/saml-2.0/samlp2_status_response.c b/lasso/xml/saml-2.0/samlp2_status_response.c
index d530dcab..96febdd9 100644
--- a/lasso/xml/saml-2.0/samlp2_status_response.c
+++ b/lasso/xml/saml-2.0/samlp2_status_response.c
@@ -173,9 +173,9 @@ class_init(LassoSamlp2StatusResponseClass *klass)
LassoSamlp2StatusResponse, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(
LassoSamlp2StatusResponse, sign_method);
- nclass->node_data->private_key_file_offset = G_STRUCT_OFFSET(LassoSaml2StatusResponse,
+ nclass->node_data->private_key_file_offset = G_STRUCT_OFFSET(LassoSamlp2StatusResponse,
private_key_file);
- nclass->node_data->certificate_file_offset = G_STRUCT_OFFSET(LassoSaml2StatusResponse,
+ nclass->node_data->certificate_file_offset = G_STRUCT_OFFSET(LassoSamlp2StatusResponse,
certificate_file);
nclass->node_data->keep_xmlnode = TRUE;
}