summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-12-23 10:56:27 +0100
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2011-12-23 10:56:27 +0100
commit7b3b7d690036f218e31d30fac12da3f089dbb737 (patch)
tree5bf40dfa0d91920d05d48ad48f149c3f39080f08
parent1907d66f1adbe2223d34144646debea6c4b5de5a (diff)
downloadlasso-7b3b7d690036f218e31d30fac12da3f089dbb737.tar.gz
lasso-7b3b7d690036f218e31d30fac12da3f089dbb737.tar.xz
lasso-7b3b7d690036f218e31d30fac12da3f089dbb737.zip
[id-ff 1.2] change websso with artifact binding to work as SAML 2.0
The old way of transmiting the assertion to return via the session is kept, but a new way more semblable to the one used in the SAML 2.0 code is added. After lasso_login_build_artifact_msg() you must save the return of lasso_profile_get_artifact_message() linked to the value of the artifact obtained via lasso_profile_get_artifact(). In the artifact-resolve endpoint you must find the artifact message corresponding to the return value of lasso_profile_get_artifact() reinstall the artifact message using lasso_profile_set_artifact_message() just before calling lasso_login_build_response_msg(). This change is necessary for ID-FF 1.2 SSO profile to work with the thin-sessions.
-rw-r--r--lasso/id-ff/login.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 3bd29ebd..9191e033 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -259,6 +259,7 @@
#include "../xml/saml_conditions.h"
#include "../xml/samlp_response.h"
#include "../xml/saml-2.0/saml2_encrypted_element.h"
+#include "../xml/misc_text_node.h"
#include "profileprivate.h"
@@ -909,12 +910,12 @@ lasso_login_build_assertion_artifact(LassoLogin *login)
gint
lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
{
- LassoProvider *remote_provider;
- LassoProfile *profile;
- gchar *url;
- xmlChar *b64_samlArt;
- char *relayState;
- gint ret = 0;
+ LassoProvider *remote_provider = NULL;
+ LassoProfile *profile = NULL;
+ gchar *url = NULL;
+ xmlChar *b64_samlArt = NULL;
+ xmlChar *relayState = NULL;
+ gint rc = 0;
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
@@ -923,7 +924,7 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
if (profile->remote_providerID == NULL) {
/* this means lasso_login_init_request was not called before */
- return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
}
IF_SAML2(profile) {
@@ -931,18 +932,18 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
if (http_method != LASSO_HTTP_METHOD_REDIRECT && http_method != LASSO_HTTP_METHOD_POST) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
}
/* ProtocolProfile must be BrwsArt */
if (login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART) {
- return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
}
/* build artifact infos */
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
if (LASSO_IS_PROVIDER(remote_provider) == FALSE)
- return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
+ goto_cleanup_with_rc(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
url = lasso_provider_get_assertion_consumer_service_url(remote_provider,
LASSO_LIB_AUTHN_REQUEST(profile->request)->AssertionConsumerServiceID);
@@ -988,12 +989,12 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
b64_samlArt = xmlStrdup((xmlChar*)login->assertionArtifact);
- relayState = (char*)xmlURIEscapeStr(
+ relayState = xmlURIEscapeStr(
(xmlChar*)LASSO_LIB_AUTHN_REQUEST(profile->request)->RelayState, NULL);
if (http_method == LASSO_HTTP_METHOD_REDIRECT) {
xmlChar *escaped_artifact = xmlURIEscapeStr(b64_samlArt, NULL);
- gchar *query;
+ gchar *query = NULL;
if (relayState == NULL) {
query = g_strdup_printf("SAMLart=%s", escaped_artifact);
@@ -1003,20 +1004,16 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
lasso_release_string(query);
-
- xmlFree(escaped_artifact);
+ lasso_release_xml_string(escaped_artifact);
}
if (http_method == LASSO_HTTP_METHOD_POST) {
lasso_assign_string(profile->msg_url, url);
lasso_assign_string(profile->msg_body, (char*)b64_samlArt);
if (relayState != NULL) {
- lasso_assign_string(profile->msg_relayState, relayState);
+ lasso_assign_string(profile->msg_relayState, (char*)relayState);
}
}
- lasso_release_string(url);
- xmlFree(b64_samlArt);
- xmlFree(relayState);
if (strcmp(LASSO_SAMLP_RESPONSE(profile->response)->Status->StatusCode->Value,
LASSO_SAML_STATUS_CODE_SUCCESS) != 0) {
@@ -1029,7 +1026,25 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
lasso_session_remove_status(profile->session, profile->remote_providerID);
}
- return ret;
+ /* store the response as the artifact message */
+ lasso_check_good_rc(lasso_server_set_signature_for_provider_by_name(
+ profile->server,
+ profile->remote_providerID,
+ profile->response));
+ /* comply with the new way of storing artifacts */
+ lasso_assign_string(profile->private_data->artifact,
+ login->assertionArtifact);
+ /* Artifact profile for ID-FF 1.2 is special, this is not the full message which is relayed
+ * but only its assertion content, the Response container is changed from a
+ * lib:AuthnResponse to a samlp:Response.
+ */
+ lasso_assign_new_string(profile->private_data->artifact_message,
+ lasso_node_export_to_xml((LassoNode*)login->assertion));
+cleanup:
+ lasso_release_string(url);
+ lasso_release_xml_string(b64_samlArt);
+ lasso_release_xml_string(relayState);
+ return rc;
}
/**
@@ -1366,8 +1381,8 @@ cleanup:
gint
lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
{
- LassoProvider *remote_provider;
- LassoProfile *profile;
+ LassoProvider *remote_provider = NULL;
+ LassoProfile *profile = NULL;
lasso_error_t rc = 0;
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
@@ -1429,6 +1444,16 @@ lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
lasso_profile_set_response_status(profile,
LASSO_SAML_STATUS_CODE_SUCCESS);
lasso_session_remove_status(profile->session, remote_providerID);
+ } else if (profile->private_data->artifact_message) {
+ xmlDoc *doc;
+ char *artifact_message = profile->private_data->artifact_message;
+ doc = lasso_xml_parse_memory(artifact_message,
+ strlen(artifact_message));
+ lasso_profile_set_response_status(profile,
+ LASSO_SAML_STATUS_CODE_SUCCESS);
+ lasso_list_add_new_gobject(((LassoSamlpResponse*)profile->response)->Assertion,
+ lasso_misc_text_node_new_with_xml_node(xmlDocGetRootElement(doc)));
+ lasso_release_doc(doc);
}
}
} else {
@@ -2177,6 +2202,8 @@ lasso_login_process_request_msg(LassoLogin *login, gchar *request_msg)
/* get AssertionArtifact */
lasso_assign_string(login->assertionArtifact,
LASSO_SAMLP_REQUEST(profile->request)->AssertionArtifact);
+ lasso_assign_string(login->parent.private_data->artifact,
+ login->assertionArtifact);
/* Keep a copy of request msg so signature can be verified when we get
* the providerId in lasso_login_build_response_msg()