From 4befad2b6edeb28bcc1ad4e0e4bd5506e2325416 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 4 Jan 2010 09:14:58 +0000 Subject: ID-WSF 2.0: create idwsf2_helper.{c,h}, new module for manipulating EPR elements * lasso/id-wsf-2.0/idwsf2_helper.c lasso/id-wsf-2.0/idwsf2_helper.h: add new functions lasso_wsa_endpoint_reference_get_idwsf2_service_type, lasso_wsa_endpoint_reference_get_idwsf2_provider_id, lasso_wsa_endpoint_reference_get_idwsf2_security_context_for_security_mechanism, lasso_wsa_endpoint_reference_get_token_by_usage, lasso_wsa_endpoint_reference_get_security_token,lasso_wsa_endpoint_reference_get_target_identity_token, lasso_wsa_endpoint_reference_new_for_idwsf2_service, and lasso_wsa_endpoint_reference_add_security_token. * lasso/id-wsf-2.0/idwsf2_helper.h: declare new functions. * lasso/id-wsf-2.0/Makefile.am: add new files to source list --- lasso/id-wsf-2.0/Makefile.am | 6 +- lasso/id-wsf-2.0/idwsf2_helper.c | 317 +++++++++++++++++++++++++++++++++++++++ lasso/id-wsf-2.0/idwsf2_helper.h | 68 +++++++++ 3 files changed, 389 insertions(+), 2 deletions(-) create mode 100644 lasso/id-wsf-2.0/idwsf2_helper.c create mode 100644 lasso/id-wsf-2.0/idwsf2_helper.h diff --git a/lasso/id-wsf-2.0/Makefile.am b/lasso/id-wsf-2.0/Makefile.am index 2f3eb3c4..e98ed44e 100644 --- a/lasso/id-wsf-2.0/Makefile.am +++ b/lasso/id-wsf-2.0/Makefile.am @@ -13,7 +13,8 @@ lasso_private_h_sources = \ private.h \ serverprivate.h \ sessionprivate.h \ - saml2_login_private.h + saml2_login_private.h \ + idwsf2_helper.h liblasso_id_wsf2_la_SOURCES = \ server.c \ @@ -23,7 +24,8 @@ liblasso_id_wsf2_la_SOURCES = \ data_service.c \ profile.c \ saml2_login.c \ - soap_binding.c + soap_binding.c \ + idwsf2_helper.c liblassoinclude_HEADERS = \ id_wsf_2.h \ diff --git a/lasso/id-wsf-2.0/idwsf2_helper.c b/lasso/id-wsf-2.0/idwsf2_helper.c new file mode 100644 index 00000000..98355103 --- /dev/null +++ b/lasso/id-wsf-2.0/idwsf2_helper.c @@ -0,0 +1,317 @@ +/* $Id: idwsf2_data_service.c 3101 2007-05-30 11:40:10Z dlaniel $ + * + * Lasso - A free implementation of the Liberty Alliance specifications. + * + * Copyright (C) 2004-2007 Entr'ouvert + * http://lasso.entrouvert.org + * + * Authors: See AUTHORS file in top-level directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "./idwsf2_helper.h" +#include "../xml/id-wsf-2.0/disco_abstract.h" +#include "../xml/id-wsf-2.0/disco_service_type.h" +#include "../xml/id-wsf-2.0/disco_provider_id.h" +#include "../xml/id-wsf-2.0/sec_token.h" +#include "../xml/id-wsf-2.0/sbf_framework.h" +#include "../xml/misc_text_node.h" +#include "../utils.h" + +/** + * SECTION: idwsf2-helper + * + * Methods to help manipulate EPR elements + */ + +/** + * lasso_wsa_endpoint_reference_get_idwsf2_service_type: + * + * Return the disco:ServiceType metadata element content + * + * Return value: (transfer-none): the content of the first disco:ServiceType metadata, or NULL if none is found. + */ +const char* +lasso_wsa_endpoint_reference_get_idwsf2_service_type(const LassoWsAddrEndpointReference *epr) +{ + LassoIdWsf2DiscoServiceType *disco2_service_type; + + g_return_val_if_fail(LASSO_IS_WSA_ENDPOINT_REFERENCE (epr) && epr->Metadata != NULL, NULL); + + /* Get the service type from the EPR */ + disco2_service_type = lasso_extract_gobject_from_list (LassoIdWsf2DiscoServiceType, + LASSO_TYPE_IDWSF2_DISCO_SERVICE_TYPE, epr->Metadata->any); + + if (disco2_service_type) { + return disco2_service_type->content; + } + + return NULL; +} + +/** + * lasso_wsa_endpoint_reference_get_idwsf2_provider_id + * @epr: a #LassoWsAddrEndpointReference object + * + * Return the provider ID from the the metadata element of the EPR. + * + * Return value: an entityID identifier or NULL if none is found, or the element is empty. + */ +const char* +lasso_wsa_endpoint_reference_get_idwsf2_provider_id(const LassoWsAddrEndpointReference *epr) +{ + LassoIdWsf2DiscoProviderID *disco2_provider_id; + + g_return_val_if_fail(LASSO_IS_WSA_ENDPOINT_REFERENCE (epr) && epr->Metadata != NULL, NULL); + + /* Get the service type from the EPR */ + disco2_provider_id = lasso_extract_gobject_from_list (LassoIdWsf2DiscoProviderID, + LASSO_TYPE_IDWSF2_DISCO_PROVIDER_ID, epr->Metadata->any); + + if (disco2_provider_id) { + return disco2_provider_id->content; + } + + return NULL; +} + +/** + * lasso_wsa_endpoint_reference_get_idwsf2_security_context_for_security_mechanism: + * @epr: a #LassoWsAddrEndpointReference object + * @security_mech_predicate: (allow-none): a predicate to test for security mechanism + * @security_mech_id: (allow-none): a security mechanism identifier + * @create: allow to create the element if none if found, @security_mech_id is mandatory when create + * is TRUE. + * + * Return value: (transfer-none): a #LassoIdWsf2DiscoSecurityContext, or NULL if none was found and + * created is FALSE. + */ +LassoIdWsf2DiscoSecurityContext* +lasso_wsa_endpoint_reference_get_idwsf2_security_context_for_security_mechanism( + const LassoWsAddrEndpointReference *epr, + gboolean (*sech_mech_predicate)(const char *), + const char *security_mech_id, + gboolean create) +{ + LassoIdWsf2DiscoSecurityContext *created = NULL; + LassoMiscTextNode *new_security_mech_id_declaration; + + g_return_val_if_fail(LASSO_IS_WSA_ENDPOINT_REFERENCE (epr) && epr->Metadata != NULL, NULL); + + lasso_foreach_full_begin(LassoIdWsf2DiscoSecurityContext*, context, it1, epr->Metadata->any); + if (LASSO_IS_IDWSF2_DISCO_SECURITY_CONTEXT (context)) { + lasso_foreach_full_begin(LassoMiscTextNode*, textnode, it2, context->SecurityMechID); + if (LASSO_IS_MISC_TEXT_NODE (textnode)) { + if (g_strcmp0 (textnode->content, security_mech_id) || sech_mech_predicate(textnode->content)) { + return context; + } + } + lasso_foreach_full_end() + } + lasso_foreach_full_end(); + + if (create && security_mech_id) { + created = lasso_idwsf2_disco_security_context_new(); + new_security_mech_id_declaration = + lasso_misc_text_node_new_with_string(security_mech_id); + new_security_mech_id_declaration->name = "SecurityMechID"; + new_security_mech_id_declaration->ns_href = LASSO_IDWSF2_DISCO_HREF; + new_security_mech_id_declaration->ns_prefix = LASSO_IDWSF2_DISCO_PREFIX; + lasso_list_add_new_gobject (created->SecurityMechID, + new_security_mech_id_declaration); + lasso_list_add_new_gobject (epr->Metadata->any, created); + } + if (create && ! security_mech_id) { + g_warning ("cannot create a LassoIdWsf2DiscoSecurityContext withou a security_mech_id"); + } + + return created; +} + +/** + * lasso_wsa_endpoint_reference_get_token_by_usage: + * @epr: a #LassoWsAddrEndpointReference object + * @security_mech_predicate: (allow-none): a predicate to test for security mechanism + * @security_mech_id: (allow-none): a security mechanism identifier + * @usage: the usage to make of the token + * + * Try to find a token for the given usage and security mechanism, the security can be chosen by + * name or by a predicate. + * + * Return value: a #LassoNode object or a subclass, representing the token. + */ +static LassoNode* +lasso_wsa_endpoint_reference_get_token_by_usage( + const LassoWsAddrEndpointReference *epr, + gboolean (*sec_mech_predicate)(const char *), + const char *security_mech_id, const char* usage) +{ + LassoIdWsf2DiscoSecurityContext *security_context; + + security_context = lasso_wsa_endpoint_reference_get_idwsf2_security_context_for_security_mechanism (epr, sec_mech_predicate, security_mech_id, TRUE); + lasso_foreach_full_begin (LassoIdWsf2SecToken*, token, iter, security_context->Token); + if (LASSO_IS_IDWSF2_SEC_TOKEN (token)) { + if (usage && g_strcmp0(token->usage, usage) == 0) { + if (LASSO_IS_NODE(token->any)) { + return (LassoNode*)token->any; + } else if (token->ref) { + g_warning ("sec:Token ref attribute is not supported"); + return NULL; + } + } + + } + lasso_foreach_full_end(); + + return NULL; +} + +/** + * lasso_wsa_endpoint_reference_get_security_token: + * @epr: a #LassoWsAddrEndpointReference object + * @sech_mech_predicate:(allow-none): a boolean function to select the security mechanism for which we want the + * security token + * @security_mech_id:(allow-none): an optional specific security mechanism identifier to select the + * security token. + * + * Return the first security token found in the metadata of the @epr object which qualify with + * respect to the predicate or the given security mechanism identifier. It is an error to pass both + * of @sech_mech_predicate and @security_mech_id as NULL. + * + * Return value:(transfer none): a #LassoNode object or NULL if the query cannot be satisfied. + */ +LassoNode* +lasso_wsa_endpoint_reference_get_security_token (const LassoWsAddrEndpointReference *epr, + gboolean (*sech_mech_predicate)(const char *), const char *security_mech_id) +{ + return lasso_wsa_endpoint_reference_get_token_by_usage (epr, sech_mech_predicate, + security_mech_id, LASSO_IDWSF2_SEC_TOKEN_USAGE_SECURITY_TOKEN); +} + +/** + * lasso_wsa_endpoint_reference_get_target_identity_token: + * @epr: a #LassoWsAddrEndpointReference object + * @sech_mech_predicate:(allow-none): a boolean function to select the security mechanism for which we want the + * security token + * @security_mech_id:(allow-none): an optional specific security mechanism identifier to select the + * security token. + * + * Return the first target identity token found in the metadata of the @epr object which qualify with + * respect to the predicate or the given security mechanism identifier. It is an error to pass both + * of @sech_mech_predicate and @security_mech_id as NULL. + * + * Return value:(transfer none): a #LassoNode object or NULL if the query cannot be satisfied. + */ +LassoNode* +lasso_wsa_endpoint_reference_get_target_identity_token(const LassoWsAddrEndpointReference *epr, + gboolean (*sech_mech_predicate)(const char *), const char *security_mech_id) +{ + return lasso_wsa_endpoint_reference_get_token_by_usage (epr, sech_mech_predicate, + security_mech_id, LASSO_IDWSF2_SEC_TOKEN_USAGE_TARGET_IDENTITY); +} + +/** + * lasso_wsa_endpoint_reference_new_for_idwsf2_service: + * @address: the URL of the SOAP endpoint where the service is anchored + * @service_type: an URI identifying the ID-WSF 2.0 service type + * @provider_id: an URI identifying the SAML 2.0 service provider hosting the service, this should + * help in finding key material for security mechanisms. + * @abstract: a human description of the service. + * + * Create and populate a new #LassoWsAddrEndpointReference object. + * + * Return value: a newly created #LassoWsAddrEndpointReference. + */ +LassoWsAddrEndpointReference* +lasso_wsa_endpoint_reference_new_for_idwsf2_service(const char *address, + const char *service_type, const char *provider_id, const char *abstract) +{ + LassoWsAddrEndpointReference *epr = NULL; + LassoWsAddrMetadata *metadata = NULL; + + /* Check parameters */ + if (address == NULL || service_type == NULL || provider_id == NULL || abstract == NULL) + return NULL; + + /* Build EndpointReference */ + epr = lasso_wsa_endpoint_reference_new(); + + /* Address */ + epr->Address = lasso_wsa_attributed_uri_new_with_string(address); + + /* Metadatas */ + metadata = lasso_wsa_metadata_new(); + + /* Abstract */ + lasso_list_add_new_gobject(metadata->any, + lasso_idwsf2_disco_abstract_new_with_string(abstract)); + + /* ProviderID */ + lasso_list_add_new_gobject(metadata->any, + lasso_idwsf2_disco_provider_id_new_with_string(provider_id)); + + /* ServiceType */ + lasso_list_add_new_gobject(metadata->any, + lasso_idwsf2_disco_service_type_new_with_string(service_type)); + + /* Framework */ + lasso_list_add_new_gobject(metadata->any, + lasso_idwsf2_sbf_framework_new_full("2.0")); + + return epr; +} + +/** + * lasso_wsa_endpoint_reference_add_security_token: + * @epr: a #LassoWsAddrEndpointReference object + * @security_token: a security token as a #LassoNode object + * @security_mechanisms:(in): a list of security mechanism for whom the token is made + * + * Add a new security context declaration for the given security mechanisms identifiers and populate + * it with a security token. + * + * Return value: 0 if successfull, an error code otherwise. + */ +int +lasso_wsa_endpoint_reference_add_security_token(LassoWsAddrEndpointReference *epr, LassoNode *security_token, const char **security_mechanisms) +{ + LassoIdWsf2SecToken *sec_token = NULL; + LassoWsAddrMetadata *metadata = NULL; + LassoIdWsf2DiscoSecurityContext *security_context = NULL; + int rc = 0; + + lasso_bad_param(WSA_ENDPOINT_REFERENCE, epr); + lasso_bad_param(NODE, security_token); + lasso_null_param(security_mechanisms); + if (security_mechanisms[0] == NULL) { + return LASSO_PARAM_ERROR_INVALID_VALUE; + } + + lasso_extract_node_or_fail(metadata, epr->Metadata, WSA_METADATA, LASSO_PARAM_ERROR_INVALID_VALUE); + + sec_token = lasso_idwsf2_sec_token_new(); + lasso_assign_gobject(sec_token->any, security_token); + + security_context = lasso_idwsf2_disco_security_context_new(); + while (security_mechanisms[0] != NULL) { + lasso_list_add_string(security_context->SecurityMechID, security_mechanisms[0]); + ++security_mechanisms; + } + lasso_list_add_new_gobject(security_context->Token, sec_token); + lasso_list_add_new_gobject(metadata->any, security_context); +cleanup: + return rc; +} diff --git a/lasso/id-wsf-2.0/idwsf2_helper.h b/lasso/id-wsf-2.0/idwsf2_helper.h new file mode 100644 index 00000000..30ee9a0d --- /dev/null +++ b/lasso/id-wsf-2.0/idwsf2_helper.h @@ -0,0 +1,68 @@ +/* $Id: wsf_profile.h,v 1.13 2006/11/14 17:07:30 Exp $ + * + * Lasso - A free implementation of the Liberty Alliance specifications. + * + * Copyright (C) 2004-2007 Entr'ouvert + * http://lasso.entrouvert.org + * + * Authors: See AUTHORS file in top-level directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LASSO_IDWSF2_HELPER_H__ +#define __LASSO_IDWSF2_HELPER_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "../xml/ws/wsa_endpoint_reference.h" +#include "../xml/id-wsf-2.0/disco_security_context.h" + + +const char* lasso_wsa_endpoint_reference_get_idwsf2_service_type( + const LassoWsAddrEndpointReference *epr); + +const char* lasso_wsa_endpoint_reference_get_idwsf2_provider_id( + const LassoWsAddrEndpointReference *epr); + +LassoIdWsf2DiscoSecurityContext* + lasso_wsa_endpoint_reference_get_idwsf2_security_context_for_security_mechanism( + const LassoWsAddrEndpointReference *epr, + gboolean (*sech_mech_predicate)(const char *), + const char *security_mech_id, + gboolean create); + +LassoNode* lasso_wsa_endpoint_reference_get_security_token (const LassoWsAddrEndpointReference *epr, + gboolean (*sech_mech_predicate)(const char *), const char *security_mech_id); + +LASSO_EXPORT LassoNode* lasso_wsa_endpoint_reference_get_target_identity_token( + const LassoWsAddrEndpointReference *epr, + gboolean (*sech_mech_predicate)(const char *), const char *security_mech_id); + +LASSO_EXPORT LassoWsAddrEndpointReference* lasso_wsa_endpoint_reference_new_for_idwsf2_service( + const char *address, const char *service_ype, const char *provider_id, + const char *abstract); + +LASSO_EXPORT int lasso_wsa_endpoint_reference_add_security_token(LassoWsAddrEndpointReference *epr, + LassoNode *security_token, const char **security_mechanisms); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __LASSO_IDWSF2_HELPER_H__ */ + -- cgit