summaryrefslogtreecommitdiffstats
path: root/lasso/id-wsf-2.0/profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'lasso/id-wsf-2.0/profile.c')
-rw-r--r--lasso/id-wsf-2.0/profile.c660
1 files changed, 547 insertions, 113 deletions
diff --git a/lasso/id-wsf-2.0/profile.c b/lasso/id-wsf-2.0/profile.c
index 62347317..5086a833 100644
--- a/lasso/id-wsf-2.0/profile.c
+++ b/lasso/id-wsf-2.0/profile.c
@@ -35,6 +35,8 @@
#include "../id-ff/serverprivate.h"
#include "../id-ff/providerprivate.h"
+#include "../saml-2.0/profileprivate.h"
+
#include "profile.h"
#include "session.h"
@@ -43,22 +45,85 @@
#include "../xml/soap_binding_provider.h"
#include "../xml/soap_binding_processing_context.h"
#include "../xml/xml_enc.h"
+#include "../xml/id-wsf-2.0/sb2_sender.h"
+#include "../xml/id-wsf-2.0/sb2_redirect_request.h"
#include "../xml/ws/wsse_security_header.h"
#include "../xml/saml-2.0/saml2_assertion.h"
#include "../utils.h"
+#include "./idwsf2_helper.h"
+#include "./soap_binding.h"
+#include "../id-wsf/utils.h"
+#include "../saml-2.0/saml2_helper.h"
-/*****************************************************************************/
-/* private methods */
-/*****************************************************************************/
+/**
+ * LassoIdWsf2ProfilePrivate:
+ * @epr: the #LassoWsAddrEndpointReference object representing the targetd service
+ */
+struct _LassoIdWsf2ProfilePrivate {
+ LassoWsAddrEndpointReference *epr;
+ LassoSoapEnvelope *soap_envelope_request;
+ LassoSoapEnvelope *soap_envelope_response;
+};
+
+#define private_accessors(type, name) \
+static type \
+_get_##name(LassoIdWsf2Profile *idwsf2_profile)\
+{ \
+ if (idwsf2_profile && idwsf2_profile->private_data) \
+ { \
+ return idwsf2_profile->private_data->name; \
+ } \
+ return 0; \
+} \
+static void \
+_set_##name(LassoIdWsf2Profile *idwsf2_profile, \
+ type what) \
+{ \
+ if (idwsf2_profile && idwsf2_profile->private_data) \
+ { \
+ lasso_assign_gobject(idwsf2_profile->private_data->name, what); \
+ } \
+}
-LassoSoapEnvelope*
-lasso_idwsf2_profile_build_soap_envelope(G_GNUC_UNUSED const char *refToMessageId, G_GNUC_UNUSED const char *providerId)
+private_accessors(LassoWsAddrEndpointReference*,epr)
+private_accessors(LassoSoapEnvelope*,soap_envelope_request)
+private_accessors(LassoSoapEnvelope*,soap_envelope_response)
+
+
+static void
+_add_fault_for_rc(LassoIdWsf2Profile *profile, int rc)
+{
+ LassoSoapFault *fault;
+ char *code;
+
+ if (rc) {
+ code = g_strdup_printf("LASSO_ERROR_%i", rc);
+ fault = lasso_soap_fault_new_full(code, lasso_strerror(rc));
+ g_free(code);
+ lasso_release_list_of_gobjects(_get_soap_envelope_response(profile)->Header->Other);
+ lasso_soap_envelope_add_to_body(_get_soap_envelope_response(profile), (LassoNode*)fault);
+ }
+}
+
+/**
+ * lasso_idwsf2_profile_build_soap_envelope:
+ * @refToMessageId: (allow-none): the string ID of the request
+ * @providerId: (allow-none): the providerID of the sender
+ *
+ * Build a new SOAP envelope, for transmitting an ID-WSF request of response. If the message is a
+ * response, refer to the request whose ID is @refToMessageId.
+ *
+ * Return value: a new #LassoSoapEnvelope if successful, NULL otherwise.
+ */
+static LassoSoapEnvelope*
+lasso_idwsf2_profile_build_soap_envelope(const char *refToMessageId, const char *providerID)
{
LassoSoapEnvelope *envelope;
LassoSoapHeader *header;
LassoSoapBody *body;
+ LassoIdWsf2Sb2Sender *sender;
/* Body */
body = lasso_soap_body_new();
@@ -69,125 +134,424 @@ lasso_idwsf2_profile_build_soap_envelope(G_GNUC_UNUSED const char *refToMessageI
header = lasso_soap_header_new();
envelope->Header = header;
+ if (providerID) {
+ /* Sender */
+ sender = lasso_idwsf2_sb2_sender_new();
+ lasso_assign_string(sender->providerID, providerID);
+ lasso_list_add_gobject(header->Other, sender);
+ }
+
+ if (refToMessageId) {
+ LassoWsAddrAttributedURI *relates_to;
+ relates_to = lasso_wsa_attributed_uri_new_with_string(refToMessageId);
+ lasso_node_set_custom_nodename((LassoNode*)relates_to, "RelatesTo");
+ lasso_list_add_gobject(header->Other, relates_to);
+ }
+
return envelope;
}
-/*****************************************************************************/
-/* public methods */
-/*****************************************************************************/
-
+/**
+ * lasso_idwsf2_profile_init_request:
+ * @profile: a #LassoIdWsf2Profile object
+ *
+ * Initialize a new SOAP ID-WSF 2.0 request. Clear the existing request if one is currently set.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
gint
-lasso_idwsf2_profile_init_soap_request(LassoIdWsf2Profile *profile, LassoNode *request,
- gchar *service_type)
+lasso_idwsf2_profile_init_request(LassoIdWsf2Profile *idwsf2_profile)
{
- LassoSoapEnvelope *envelope;
- LassoSession *session = LASSO_PROFILE(profile)->session;
- LassoSaml2Assertion *assertion;
- LassoWsSec1SecurityHeader *wsse_security;
-
- /* Initialise soap envelope */
- envelope = lasso_idwsf2_profile_build_soap_envelope(NULL,
- LASSO_PROVIDER(LASSO_PROFILE(profile)->server)->ProviderID);
- lasso_assign_new_gobject(profile->soap_envelope_request, envelope);
-
- /* Add identity token (if it exists in the session) in soap header */
- assertion = lasso_session_get_assertion_identity_token(session, service_type);
-
- /* FIXME: use sb2:TargetIdentity if security mech is :null */
- if (assertion != NULL) {
- wsse_security = lasso_wsse_security_header_new();
- lasso_list_add_new_gobject(wsse_security->any, assertion);
- lasso_list_add_new_gobject(envelope->Header->Other, wsse_security);
+ LassoSoapEnvelope *envelope = NULL;
+ LassoProfile *profile = NULL;
+ LassoWsAddrEndpointReference *epr;
+ const char *provider_id = NULL;
+ int rc = 0;
+
+ lasso_bad_param(IDWSF2_PROFILE, idwsf2_profile);
+ profile = &idwsf2_profile->parent;
+ epr = lasso_idwsf2_profile_get_epr(idwsf2_profile);
+
+ if (epr) {
+ LassoIdWsf2DiscoSecurityContext *security_context;
+
+ security_context =
+ lasso_wsa_endpoint_reference_get_idwsf2_security_context_for_security_mechanism(
+ epr, lasso_security_mech_id_is_bearer_authentication, NULL, FALSE);
+ if (! security_context) {
+ return LASSO_WSF_PROFILE_ERROR_UNSUPPORTED_SECURITY_MECHANISM;
+ }
}
- /* Add the given request in soap body */
- lasso_list_add_gobject(envelope->Body->any, request);
+ if (LASSO_IS_SERVER(profile->server)) {
+ provider_id = profile->server->parent.ProviderID;
+ }
+ envelope = lasso_idwsf2_profile_build_soap_envelope(NULL, provider_id);
+ _set_soap_envelope_request(idwsf2_profile, envelope);
+ lasso_release_gobject(profile->request);
- return 0;
+ lasso_release_gobject(envelope);
+ return rc;
}
+/**
+ * lasso_idwsf2_profile_init_response:
+ * @profile: a #LassoIdWsf2Profile object
+ *
+ * Initialize a new SOAP ID-WSF 2.0 response. Clear the existing response if one is currently set.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
gint
-lasso_idwsf2_profile_build_request_msg(LassoIdWsf2Profile *profile)
+lasso_idwsf2_profile_init_response(LassoIdWsf2Profile *profile)
{
- g_return_val_if_fail(LASSO_IS_IDWSF2_PROFILE(profile),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
+ char *provider_id = NULL;
+ LassoSoapEnvelope *soap_envelope;
+ char *request_message_id = NULL;
+ int rc = 0;
+
+ lasso_bad_param(IDWSF2_PROFILE, profile);
+
+ if (LASSO_IS_SERVER(profile->parent.server)) {
+ provider_id = profile->parent.server->parent.ProviderID;
+ }
+ request_message_id = lasso_soap_envelope_get_message_id(
+ lasso_idwsf2_profile_get_soap_envelope_request(profile));
+ soap_envelope = lasso_idwsf2_profile_build_soap_envelope(request_message_id, provider_id);
+ _set_soap_envelope_response(profile, soap_envelope);
+ lasso_release_gobject(profile->parent.response);
+
+ return rc;
+}
+
+/**
+ * lasso_idwsf2_profile_build_request_msg:
+ * @profile: a #LassoIdWsf2Profile object
+ *
+ * Serialize and sign, if needed, the SOAP request message, put the result in
+ * <programlisting>LASSO_PROFILE(profile)->msg_body</paramlisting>.
+ *
+ * FIXME: really do sign messages.
+ *
+ * Return value: 0 if successful, LASSO_PROFILE_ERROR_BUILDING_REQUEST_FAILED.
+ */
+gint
+lasso_idwsf2_profile_build_request_msg(LassoIdWsf2Profile *profile, const char *security_mech_id)
+{
+ LassoWsAddrEndpointReference *epr;
+ LassoSoapEnvelope *envelope;
+
+ lasso_bad_param(IDWSF2_PROFILE, profile);
+ epr = lasso_idwsf2_profile_get_epr(profile);
+ envelope = _get_soap_envelope_request(profile);
+
+ /* Handle SOAP Binding and WS-Security, when given an EPR */
+ if (LASSO_IS_WSA_ENDPOINT_REFERENCE(epr)) {
+ if (epr->Address != NULL) {
+ lasso_assign_string(profile->parent.msg_url, epr->Address->content);
+ }
+
+ /* Default try bearer */
+ if (security_mech_id == NULL || lasso_security_mech_id_is_bearer_authentication(
+ security_mech_id)) {
+ LassoNode *security_token;
+
+ security_token = lasso_wsa_endpoint_reference_get_security_token(epr,
+ lasso_security_mech_id_is_bearer_authentication, NULL);
+ if (security_token) {
+ lasso_soap_envelope_add_security_token (envelope, security_token);
+ } else {
+ g_warning ("No security mechanism specified, " \
+ "failed to find security token for Bearer mechanism");
+ }
+ if (lasso_wsa_endpoint_reference_get_target_identity_token(epr,
+ lasso_security_mech_id_is_bearer_authentication, NULL) != NULL) {
+ g_critical("TargetIdentity token are not supported");
+ }
+ } else {
+ g_critical("Only Bearer security mechanism is supported by ID-WSF 2.0 module of Lasso");
+ }
+ }
LASSO_PROFILE(profile)->msg_body = lasso_node_export_to_xml(
- LASSO_NODE(profile->soap_envelope_request));
+ LASSO_NODE(_get_soap_envelope_request(profile)));
+
+ if (! LASSO_PROFILE(profile)->msg_body)
+ return LASSO_PROFILE_ERROR_BUILDING_REQUEST_FAILED;
return 0;
}
+/**
+ * lasso_idwsf2_profile_process_request_msg:
+ * @wsf2_profile: a #LassoIdWsf2Profile object
+ * @message: a received SOAP message
+ *
+ * Parse a SOAP request message and initialize the SOAP Envelope for the response.
+ *
+ * Return value: 0 if successful, an error code otherwise among:
+ * <itemizedlist>
+ * <listitem><para>LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if @profile is not a #LassoIdWsf2Profile
+ * object,</para></listitem>
+ * <listitem><para>LASSO_PARAM_ERROR_INVALID_VALUE if message is NULL,</para></listitem>
+ * <listitem><para>LASSO_PROFILE_ERROR_INVALID_MSG if we cannot parse the message,</para></listitem>
+ * <listitem><para>LASSO_SOAP_ERROR_MISSING_BODY if the message has no body
+ * content.</para></listitem>
+ * <itemizedlist>
+ */
gint
-lasso_idwsf2_profile_process_soap_request_msg(LassoIdWsf2Profile *wsf2_profile, const gchar *message)
+lasso_idwsf2_profile_process_request_msg(LassoIdWsf2Profile *wsf2_profile, const gchar *message)
{
LassoProfile *profile = NULL;
LassoSoapEnvelope *envelope = NULL;
+ char *message_id;
+ char *provider_id;
int rc = 0;
- g_return_val_if_fail(LASSO_IS_IDWSF2_PROFILE(wsf2_profile),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ lasso_bad_param(IDWSF2_PROFILE, wsf2_profile);
+ lasso_check_non_empty_string(message);
+
+ /* Clean some fields */
+ lasso_release_gobject(wsf2_profile->parent.nameIdentifier);
+ lasso_release_string(wsf2_profile->parent.remote_providerID);
+ lasso_release_string(wsf2_profile->parent.msg_body);
+ lasso_release_gobject(wsf2_profile->private_data->soap_envelope_response);
+ lasso_release_gobject(wsf2_profile->parent.response);
/* Get soap request */
profile = LASSO_PROFILE(wsf2_profile);
- lasso_assign_new_gobject(wsf2_profile->soap_envelope_request, lasso_soap_envelope_new_from_message(message));
- if (! LASSO_IS_SOAP_ENVELOPE(wsf2_profile->soap_envelope_request)) {
+
+ lasso_assign_new_gobject(wsf2_profile->private_data->soap_envelope_request,
+ lasso_soap_envelope_new_from_message(message));
+ if (! LASSO_IS_SOAP_ENVELOPE(_get_soap_envelope_request(wsf2_profile))) {
return LASSO_PROFILE_ERROR_INVALID_MSG;
}
- envelope = wsf2_profile->soap_envelope_request;
+ envelope = _get_soap_envelope_request(wsf2_profile);
if (envelope != NULL && envelope->Body != NULL && envelope->Body->any != NULL &&
LASSO_IS_NODE(envelope->Body->any->data)) {
- lasso_assign_gobject(LASSO_PROFILE(profile)->request, (LassoNode*)envelope->Body->any->data);
+ lasso_assign_gobject(profile->request, envelope->Body->any->data);
} else {
rc = LASSO_SOAP_ERROR_MISSING_BODY;
}
/* Initialize soap response */
- lasso_assign_new_gobject(wsf2_profile->soap_envelope_response, lasso_idwsf2_profile_build_soap_envelope(NULL,
- LASSO_PROVIDER(profile->server)->ProviderID));
+ message_id = lasso_soap_envelope_get_message_id(
+ _get_soap_envelope_request(wsf2_profile));
+ if (LASSO_IS_SERVER(profile->server)) {
+ provider_id = profile->server->parent.ProviderID;
+ lasso_assign_new_gobject(wsf2_profile->private_data->soap_envelope_response,
+ lasso_idwsf2_profile_build_soap_envelope(message_id, provider_id));
+ }
+ _add_fault_for_rc(wsf2_profile, rc);
+cleanup:
return rc;
}
+/**
+ * lasso_idwsf2_profile_check_security_mechanism:
+ * @profile: a #LassoIdWsf2Profile object
+ * @security_mech_id:(allow-none): the security mechanism to enforce, if none is provided Bearer is
+ * assumed.
+ *
+ * Check ID-WSF 2.0 Security Mechanism upon the received request.
+ *
+ * Return value: 0 if the request passed the check, an error code otherwise.
+ */
gint
-lasso_idwsf2_profile_build_response_msg(LassoIdWsf2Profile *profile)
+lasso_idwsf2_profile_check_security_mechanism(LassoIdWsf2Profile *profile,
+ const char *security_mech_id)
{
- g_return_val_if_fail(LASSO_IS_IDWSF2_PROFILE(profile),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
-
- LASSO_PROFILE(profile)->msg_body = lasso_node_export_to_xml(LASSO_NODE(
- profile->soap_envelope_response));
+ LassoSoapEnvelope *envelope = NULL;
+ int rc = LASSO_WSF_PROFILE_ERROR_SECURITY_MECHANISM_CHECK_FAILED;
+
+ lasso_bad_param(IDWSF2_PROFILE, profile);
+ envelope = _get_soap_envelope_request(profile);
+ /* Verify security mechanism */
+ if (security_mech_id == NULL ||
+ lasso_security_mech_id_is_bearer_authentication(security_mech_id)) {
+ LassoSaml2Assertion *assertion;
+ LassoProvider *issuer;
+
+ assertion = lasso_soap_envelope_get_saml2_security_token (envelope);
+ if (assertion == NULL)
+ goto cleanup;
+ if (! lasso_saml2_assertion_validate_conditions(assertion, NULL))
+ goto cleanup;
+ issuer = lasso_saml2_assertion_get_issuer_provider(assertion, profile->parent.server);
+ if (! issuer || issuer->role != LASSO_PROVIDER_ROLE_IDP)
+ goto cleanup;
+ if (lasso_provider_verify_single_node_signature(issuer, (LassoNode*)assertion, "ID") != 0)
+ goto cleanup;
+ } else {
+ g_warning("Only Bearer mechanism is supported!");
+ rc = LASSO_ERROR_UNIMPLEMENTED;
+ goto cleanup;
+ }
+ rc = 0;
+cleanup:
+ _add_fault_for_rc(profile, rc);
+ return rc;
+}
- return 0;
+/**
+ * lasso_idwsf2_profile_init_soap_fault_response:
+ * @profile: a #LassoIdWsf2Profile object
+ *
+ * Initialize a new SOAP 1.1 fault.
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
+gint
+lasso_idwsf2_profile_init_soap_fault_response(LassoIdWsf2Profile *profile)
+{
+ int rc = 0;
+ LassoSoapEnvelope *envelope;
+ LassoSoapFault *fault;
+
+ lasso_check_good_rc(lasso_idwsf2_profile_init_response(profile));
+ envelope = lasso_idwsf2_profile_get_soap_envelope_response(profile);
+ if (envelope) {
+ fault = lasso_soap_fault_new();
+ lasso_list_add_new_gobject(envelope->Body->any, fault);
+ lasso_assign_gobject(profile->parent.response, fault);
+ }
+cleanup:
+ return rc;
}
+/**
+ * lasso_idwsf2_profile_redirect_user_for_interaction:
+ * @profile: a #LassoIdWsf2Profile object
+ * @redirect_url: an URL where the user must be redirected
+ *
+ * Create a SOAP fault asking for user
+ *
+ * Return value: 0 if successful, an error code otherwise.
+ */
gint
-lasso_idwsf2_profile_process_soap_response_msg(LassoIdWsf2Profile *profile, const gchar *message)
+lasso_idwsf2_profile_redirect_user_for_interaction(
+ LassoIdWsf2Profile *profile, const gchar *redirect_url, gboolean for_data)
{
- LassoSoapEnvelope *envelope = NULL;
- int res = 0;
+ LassoSoapFault *fault = NULL;
+ LassoIdWsf2Sb2RedirectRequest *redirect_request = NULL;
+ LassoIdWsf2Sb2UserInteractionHint hint;
+ int rc = 0;
- g_return_val_if_fail(LASSO_IS_IDWSF2_PROFILE(profile),
- LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
- g_return_val_if_fail(message != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
+ lasso_bad_param(IDWSF2_PROFILE, profile);
+ lasso_check_non_empty_string(redirect_url);
+
+ hint = lasso_soap_envelope_get_sb2_user_interaction_hint(
+ lasso_idwsf2_profile_get_soap_envelope_request(profile));
+ switch (hint) {
+ case LASSO_IDWSF2_SB2_USER_INTERACTION_HINT_DO_NOT_INTERACT:
+ return LASSO_WSF_PROFILE_ERROR_SERVER_INTERACTION_REQUIRED;
+ case LASSO_IDWSF2_SB2_USER_INTERACTION_HINT_DO_NOT_INTERACT_FOR_DATA:
+ if (for_data) {
+ return LASSO_WSF_PROFILE_ERROR_SERVER_INTERACTION_REQUIRED_FOR_DATA;
+ }
+ default:
+ break;
+ }
- /* Get soap response */
- envelope = lasso_soap_envelope_new_from_message(message);
+ lasso_check_good_rc(lasso_idwsf2_profile_init_soap_fault_response(profile));
+ fault = (LassoSoapFault*)profile->parent.response;
+ lasso_assign_string(fault->faultcode, LASSO_SOAP_FAULT_CODE_SERVER);
+ lasso_assign_string(fault->faultstring, "Server error");
+ redirect_request = lasso_idwsf2_sb2_redirect_request_new_full(redirect_url);
+ lasso_soap_fault_add_to_detail(fault, (LassoNode*)redirect_request);
+
+cleanup:
+ lasso_release_gobject(redirect_request);
+ return rc;
+}
+/**
+ * lasso_idwsf2_profile_build_response_msg:
+ * @idwsf2_profile: a #LassoIdWsf2Profile object
+ *
+ * Serialize and sign the SOAP, if needed, the response message, put the result in
+ * <programlisting>LASSO_PROFILE(profile)->msg_body</paramlisting>.
+ *
+ * Return value: 0 if successful, LASSO_PROFILE_ERROR_BUILDING_RESPONSE_FAILED otherwise.
+ */
+gint
+lasso_idwsf2_profile_build_response_msg(LassoIdWsf2Profile *idwsf2_profile)
+{
+ LassoSoapEnvelope *envelope;
- lasso_assign_new_gobject(profile->soap_envelope_response, envelope);
+ lasso_bad_param(IDWSF2_PROFILE, idwsf2_profile);
- if (envelope != NULL && envelope->Body != NULL && envelope->Body->any != NULL) {
- lasso_assign_gobject(LASSO_PROFILE(profile)->response, LASSO_NODE(envelope->Body->any->data));
- } else {
- res = LASSO_SOAP_ERROR_MISSING_BODY;
+ envelope = lasso_idwsf2_profile_get_soap_envelope_response(idwsf2_profile);
+ if (envelope == NULL) {
+ return LASSO_PROFILE_ERROR_MISSING_RESPONSE;
}
+ idwsf2_profile->parent.msg_body = lasso_node_export_to_xml((LassoNode*)envelope);
- if (LASSO_PROFILE(profile)->response == NULL) {
- res = LASSO_PROFILE_ERROR_MISSING_RESPONSE;
+ if (! LASSO_PROFILE(idwsf2_profile)->msg_body) {
+ return LASSO_PROFILE_ERROR_BUILDING_RESPONSE_FAILED;
}
+ return 0;
+}
- return res;
+/**
+ * lasso_idwsf2_profile_process_response_msg:
+ * @profile: a #LassoIdWsf2Profile object
+ * @message: a string containing a response message
+ *
+ * Parse a response received by SOAP. Place the parsed message in the #LassoIdWsf2Profile structure
+ * in the @soap_envelope_response field and the content of the body in the @response field.
+ *
+ * Return value: 0 if successful, one of those error codes if the call fails: <itemizedlist>
+ * <listitem><para>LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if first parameter is not
+ * a #LassoIdWsf2Profile object,</para></listitem>
+ * <listitem><para>LASSO_PARAM_ERROR_INVALID_VALUE if message is NULL,</para></listitem>
+ * <listitem><para>LASSO_SOAP_ERROR_MISSING_BODY if no body element is found,</para></listitem>
+ * <listitem><para>LASSO_PROFILE_ERROR_MISSING_RESPONSE if the body element is
+ * empty.</para></listitem>
+ */
+gint
+lasso_idwsf2_profile_process_response_msg(LassoIdWsf2Profile *profile, const gchar *message)
+{
+ LassoSoapEnvelope *envelope = NULL;
+ int rc = 0;
+
+ lasso_bad_param(IDWSF2_PROFILE, profile);
+ lasso_check_non_empty_string(message);
+
+ envelope = lasso_soap_envelope_new_from_message(message);
+ _set_soap_envelope_response(profile, envelope);
+
+ goto_cleanup_if_fail_with_rc (envelope != NULL,
+ LASSO_PROFILE_ERROR_INVALID_RESPONSE);
+ goto_cleanup_if_fail_with_rc (envelope->Body != NULL,
+ LASSO_SOAP_ERROR_MISSING_BODY);
+ goto_cleanup_if_fail_with_rc (envelope->Body->any != NULL &&
+ LASSO_IS_NODE(envelope->Body->any->data),
+ LASSO_PROFILE_ERROR_MISSING_RESPONSE);
+
+ lasso_assign_gobject(profile->parent.response,
+ envelope->Body->any->data);
+
+ if (LASSO_IS_SOAP_FAULT(profile->parent.response)) {
+ LassoSoapFault *fault = (LassoSoapFault*)profile->parent.response;
+ if (LASSO_IS_SOAP_DETAIL(fault->Detail)) {
+ LassoIdWsf2Sb2RedirectRequest *redirect_request;
+ redirect_request =
+ lasso_extract_gobject_from_list(
+ LassoIdWsf2Sb2RedirectRequest,
+ LASSO_TYPE_IDWSF2_SB2_REDIRECT_REQUEST,
+ fault->Detail->any);
+ if (redirect_request) {
+ lasso_assign_string(profile->parent.msg_url, redirect_request->redirectURL);
+ return LASSO_WSF_PROFILE_ERROR_REDIRECT_REQUEST;
+ }
+ return LASSO_WSF_PROFILE_ERROR_SOAP_FAULT;
+
+ }
+ }
+
+cleanup:
+ return rc;
}
/**
@@ -196,12 +560,13 @@ lasso_idwsf2_profile_process_soap_response_msg(LassoIdWsf2Profile *profile, cons
*
* Return the last parsed SOAP request object.
*
- * Return value: a #LassoSoapEnvelope object or NULL if no request as ever been parsed with this
- * object. You must free this object.
+ * Return value:(transfer none): a #LassoSoapEnvelope object or NULL if no request as ever been
+ * parsed with this object. You must free this object.
*/
-LassoSoapEnvelope* lasso_idwsf2_profile_get_soap_envelope_request(LassoIdWsf2Profile *idwsf2_profile)
+LassoSoapEnvelope*
+lasso_idwsf2_profile_get_soap_envelope_request(LassoIdWsf2Profile *idwsf2_profile)
{
- return g_object_ref(idwsf2_profile->soap_envelope_request);
+ return _get_soap_envelope_request(idwsf2_profile);
}
@@ -211,59 +576,133 @@ LassoSoapEnvelope* lasso_idwsf2_profile_get_soap_envelope_request(LassoIdWsf2Pro
*
* Return the last parsed SOAP response object.
*
- * Return value: a #LassoSoapEnvelope object or NULL if no response as ever been parsed with this
- * object. You must free this object.
+ * Return value:(transfer none): a #LassoSoapEnvelope object or NULL if no response as ever been
+ * parsed with this objects. You must free this object.
*/
-LassoSoapEnvelope* lasso_idwsf2_profile_get_soap_envelope_response(LassoIdWsf2Profile *idwsf2_profile)
+LassoSoapEnvelope*
+lasso_idwsf2_profile_get_soap_envelope_response(LassoIdWsf2Profile *idwsf2_profile)
{
- return g_object_ref(idwsf2_profile->soap_envelope_response);
+ return _get_soap_envelope_response(idwsf2_profile);
}
/**
- * lasso_idwsf2_profile_set_response:
+ * lasso_idwsf2_profile_get_name_identifier:
* @idwsf2_profile: a #LassoIdWsf2Profile object
- * @response: (transfer full) (allow-none): a #LassoNode to set as the new content of the SOAP
- * response
*
- * Replace the current content of the response with node.
+ * Return the NameIdentifier found in a WS-Security authentication token, when Bearer or SAML
+ * security mechanism is used.
*
+ * Return value: (allow-none): a #LassoNode object or NULL.
*/
-void
-lasso_idwsf2_profile_set_response(LassoIdWsf2Profile *idwsf2_profile, LassoNode *response)
+LassoNode *
+lasso_idwsf2_profile_get_name_identifier(LassoIdWsf2Profile *idwsf2_profile)
{
- if (! LASSO_IDWSF2_PROFILE(idwsf2_profile) || !idwsf2_profile->soap_envelope_response ||
- ! idwsf2_profile->soap_envelope_response->Body)
- return;
- lasso_assign_new_gobject(((LassoProfile*)idwsf2_profile)->response, response);
- lasso_release_list_of_gobjects(idwsf2_profile->soap_envelope_response->Body->any);
- lasso_list_add_gobject(idwsf2_profile->soap_envelope_response->Body->any, response);
- return;
+ LassoSaml2Assertion *assertion = NULL;
+ LassoSaml2NameID *nameID = NULL;
+ LassoIdWsf2Sb2TargetIdentity *target_identity = NULL;
+ LassoSaml2EncryptedElement *encryptedID = NULL;
+
+
+ if (! LASSO_IS_IDWSF2_PROFILE(idwsf2_profile))
+ return NULL;
+
+ /** Already extracted, return it */
+ if (idwsf2_profile->parent.nameIdentifier != NULL)
+ goto cleanup;
+
+ /* Try to get a SAML2 assertion */
+ assertion = lasso_soap_envelope_get_saml2_security_token
+ (lasso_idwsf2_profile_get_soap_envelope_request(idwsf2_profile));
+ if (assertion && assertion->Subject) {
+
+ /* We need a server object to check for audience and decrypt encrypted NameIDs */
+ if (! LASSO_IS_SERVER(idwsf2_profile->parent.server)) {
+ goto cleanup;
+ }
+
+ /* Check validity of the assertion */
+ /* FIXME: get tolerance from profile */
+ if (lasso_saml2_assertion_validate_conditions(assertion,
+ idwsf2_profile->parent.server->parent.ProviderID) !=
+ LASSO_SAML2_ASSERTION_VALID) {
+ goto cleanup;
+ }
+
+ lasso_assign_gobject (nameID, assertion->Subject->NameID);
+ lasso_assign_gobject (encryptedID, assertion->Subject->EncryptedID);
+ }
+ if (!nameID && !encryptedID) {
+ GList *it;
+ /* Go look at the target identity */
+ target_identity = lasso_soap_envelope_sb2_get_target_identity_header (
+ lasso_idwsf2_profile_get_soap_envelope_request (idwsf2_profile));
+ if (target_identity) {
+ lasso_foreach (it, target_identity->any)
+ {
+ if (LASSO_IS_SAML2_NAME_ID(it->data)) {
+ lasso_assign_gobject (nameID, it->data);
+ break;
+ }
+ if (LASSO_IS_SAML2_ENCRYPTED_ELEMENT(it->data)) {
+ lasso_assign_gobject (encryptedID, it->data);
+ break;
+ }
+ }
+ }
+
+ }
+
+ if (lasso_saml20_profile_process_name_identifier_decryption(&idwsf2_profile->parent, &nameID,
+ &encryptedID) != 0) {
+ g_warning("process_name_identifier_decryption failed "\
+ "when retrieving name identifier for ID-WSF profile");
+ }
+ if (nameID) {
+ goto cleanup;
+ }
+
+cleanup:
+ lasso_release_gobject (assertion);
+ lasso_release_gobject (encryptedID);
+ lasso_assign_gobject (idwsf2_profile->parent.nameIdentifier, nameID);
+ return (LassoNode*)nameID;
}
/**
- * lasso_idwsf2_profile_set_request:
+ * lasso_idwsf2_profile_get_epr:
* @idwsf2_profile: a #LassoIdWsf2Profile object
- * @request: (transfer full) (allow-none): a #LassoNode to set as the new content of the SOAP
- * request.
+ * @epr: a #LassoWsAddrEndpointReference object
*
- * Replace the current content of the request with node.
+ * Set the EPR for the service targeted by the profile object.
*
*/
void
-lasso_idwsf2_profile_set_request(LassoIdWsf2Profile *idwsf2_profile, LassoNode *request)
+lasso_idwsf2_profile_set_epr(LassoIdWsf2Profile *idwsf2_profile,
+ LassoWsAddrEndpointReference *epr)
{
- if (! LASSO_IDWSF2_PROFILE(idwsf2_profile) || !idwsf2_profile->soap_envelope_request ||
- ! idwsf2_profile->soap_envelope_request->Body)
+ if (! LASSO_IS_IDWSF2_PROFILE(idwsf2_profile) || ! LASSO_IS_WSA_ENDPOINT_REFERENCE(epr) ||
+ ! idwsf2_profile->private_data)
return;
- lasso_assign_new_gobject(((LassoProfile*)idwsf2_profile)->request, request);
- lasso_release_list_of_gobjects(idwsf2_profile->soap_envelope_request->Body->any);
- lasso_list_add_gobject(idwsf2_profile->soap_envelope_request->Body->any, request);
- return;
+ _set_epr(idwsf2_profile, epr);
}
-/*****************************************************************************/
-/* overridden parent class methods */
-/*****************************************************************************/
+
+/**
+ * lasso_idwsf2_profile_get_epr:
+ * @idwsf2_profile: a #LassoIdWsf2Profile object
+ *
+ * Return the EPR used by this profile.
+ *
+ * Return value:(transfer none): a #LassoWsAddrEndpointReference object, or NULL if none is set.
+ */
+LassoWsAddrEndpointReference*
+lasso_idwsf2_profile_get_epr(LassoIdWsf2Profile *idwsf2_profile)
+{
+ if (! LASSO_IS_IDWSF2_PROFILE(idwsf2_profile) || ! idwsf2_profile->private_data)
+ return NULL;
+ return _get_epr(idwsf2_profile);
+}
+
static LassoNodeClass *parent_class = NULL;
@@ -272,21 +711,16 @@ dispose(GObject *object)
{
LassoIdWsf2Profile *profile = LASSO_IDWSF2_PROFILE(object);
- lasso_release_gobject(profile->soap_envelope_request);
- lasso_release_gobject(profile->soap_envelope_response);
+ lasso_release_gobject(profile->private_data->soap_envelope_request);
+ lasso_release_gobject(profile->private_data->soap_envelope_response);
G_OBJECT_CLASS(parent_class)->dispose(object);
}
-/*****************************************************************************/
-/* instance and class init functions */
-/*****************************************************************************/
-
static void
-instance_init(LassoIdWsf2Profile *profile)
+instance_init(LassoIdWsf2Profile *discovery)
{
- profile->soap_envelope_request = NULL;
- profile->soap_envelope_response = NULL;
+ discovery->private_data = g_new0(LassoIdWsf2ProfilePrivate, 1);
}
static void