From 904e23d7ff6283ece15dc0dffa7a61c03cc66a07 Mon Sep 17 00:00:00 2001 From: John Dennis Date: Tue, 26 May 2015 13:13:33 -0400 Subject: [PATCH] Enhance process soap response to include processing soap headers The existing lasso_saml20_profile_process_soap_response() assumed there were no SOAP headers (prior to ECP none of the SOAP messages contained headers). A new function lasso_saml20_profile_process_soap_response_with_headers() was implemented that serializes from the XML SOAP headers into a LassoSoapHeader node and optionally will return the LassoSoapHeader node. The functionality in lasso_saml20_profile_process_soap_response() was moved into the new lasso_saml20_profile_process_soap_response_with_headers() and now lasso_saml20_profile_process_soap_response() simply calls lasso_saml20_profile_process_soap_response_with_headers() passing NULL for the header return. Signed-off-by: John Dennis License: MIT --- lasso/saml-2.0/profile.c | 58 ++++++++++++++++++++++++++++++++- lasso/saml-2.0/profileprivate.h | 2 ++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lasso/saml-2.0/profile.c b/lasso/saml-2.0/profile.c index 465cbb27..c2a785f4 100644 --- a/lasso/saml-2.0/profile.c +++ b/lasso/saml-2.0/profile.c @@ -38,6 +38,7 @@ #include "../id-ff/login.h" #include "../xml/private.h" +#include "../xml/soap-1.1/soap_envelope.h" #include "../xml/saml-2.0/samlp2_request_abstract.h" #include "../xml/saml-2.0/samlp2_artifact_resolve.h" #include "../xml/saml-2.0/samlp2_artifact_response.h" @@ -1438,8 +1439,33 @@ cleanup: int lasso_saml20_profile_process_soap_response(LassoProfile *profile, const char *response_msg) +{ + return lasso_saml20_profile_process_soap_response_with_headers( + profile, response_msg, NULL); +} + +/** + * lasso_saml20_profile_process_soap_response_with_headers: + * @profile: the SAML 2.0 #LassoProfile object + * @response_msg: xml response message + * @header_return: If non-NULL the soap headers are returned at this + * pointer as a #LassoSoapHeader object. + * + * Generic method for processing SAML 2.0 protocol message as a SOAP response. + * The SOAP headers are returned via the header_return parameter + * if the parameter is non-NULL. The caller is responsible for freeing + * the SOAP header by calling lasso_release_gobject(). + * + * Return value: 0 if successful; an error code otherwise. + */ +int +lasso_saml20_profile_process_soap_response_with_headers(LassoProfile *profile, + const char *response_msg, LassoSoapHeader **header_return) { int rc = 0; + LassoSoapEnvelope *envelope = NULL; + LassoSoapHeader *header = NULL; + LassoSoapBody *body = NULL; LassoSaml2NameID *issuer = NULL; LassoProvider *remote_provider = NULL; LassoServer *server = NULL; @@ -1447,9 +1473,38 @@ lasso_saml20_profile_process_soap_response(LassoProfile *profile, lasso_bad_param(PROFILE, profile); lasso_null_param(response_msg); + if (header_return) { + *header_return = NULL; + } profile->signature_status = 0; - lasso_assign_new_gobject(profile->response, lasso_node_new_from_soap(response_msg)); + + /* Get the SOAP envelope */ + lasso_extract_node_or_fail(envelope, lasso_soap_envelope_new_from_message(response_msg), + SOAP_ENVELOPE, LASSO_PROFILE_ERROR_INVALID_SOAP_MSG); + + /* Get and validate the SOAP body, assign it to the profile response */ + lasso_extract_node_or_fail(body, envelope->Body, SOAP_BODY, + LASSO_SOAP_ERROR_MISSING_BODY); + if (body->any && LASSO_IS_NODE(body->any->data)) { + lasso_assign_gobject(profile->response, body->any->data); + } else { + lasso_release_gobject(profile->response); + goto_cleanup_with_rc(LASSO_SOAP_ERROR_MISSING_BODY); + } + + /* Get the optional SOAP header, validate it, optionally return it */ + if (envelope->Header) { + lasso_extract_node_or_fail(header, envelope->Header, SOAP_HEADER, + LASSO_PROFILE_ERROR_INVALID_SOAP_MSG); + } + if (header_return) { + if (header) { + lasso_assign_gobject(*header_return, header); + } + } + + /* Extract and validate the response data */ lasso_extract_node_or_fail(response_abstract, profile->response, SAMLP2_STATUS_RESPONSE, LASSO_PROFILE_ERROR_INVALID_MSG); lasso_extract_node_or_fail(server, profile->server, SERVER, @@ -1478,6 +1533,7 @@ lasso_saml20_profile_process_soap_response(LassoProfile *profile, } cleanup: + lasso_release_gobject(envelope); return rc; } diff --git a/lasso/saml-2.0/profileprivate.h b/lasso/saml-2.0/profileprivate.h index afc86aaf..c84c498a 100644 --- a/lasso/saml-2.0/profileprivate.h +++ b/lasso/saml-2.0/profileprivate.h @@ -34,6 +34,7 @@ extern "C" { #include "../xml/saml-2.0/samlp2_status_response.h" #include "../xml/saml-2.0/samlp2_request_abstract.h" #include "../xml/saml-2.0/saml2_subject.h" +#include "../xml/soap-1.1/soap_header.h" #include "../id-ff/provider.h" int lasso_saml20_profile_init_request(LassoProfile *profile, const char *remote_provider_id, @@ -58,6 +59,7 @@ gint lasso_saml20_profile_process_name_identifier_decryption(LassoProfile *profi LassoSaml2NameID **name_id, LassoSaml2EncryptedElement **encrypted_id); 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_soap_response_with_headers(LassoProfile *profile, const char *response_msg, LassoSoapHeader **return_header); int lasso_saml20_profile_process_any_request(LassoProfile *profile, LassoNode *request_node, const char *request_msg); int lasso_saml20_profile_process_any_response(LassoProfile *profile, LassoSamlp2StatusResponse *response_node, LassoHttpMethod *response_method, const char *response_msg);