382 lines
13 KiB
C
382 lines
13 KiB
C
/* $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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "idwsf2_helper.h"
|
|
#include "../xml/id-wsf-2.0/idwsf2_strings.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;
|
|
|
|
if (! LASSO_IS_WSA_ENDPOINT_REFERENCE (epr) || epr->Metadata == NULL)
|
|
return NULL;
|
|
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;
|
|
|
|
if (! LASSO_IS_WSA_ENDPOINT_REFERENCE (epr) || epr->Metadata == NULL)
|
|
return 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;
|
|
|
|
if (! LASSO_IS_WSA_ENDPOINT_REFERENCE (epr) || epr->Metadata == NULL)
|
|
return NULL;
|
|
|
|
lasso_foreach_full_begin(LassoIdWsf2DiscoSecurityContext*, context, it1, epr->Metadata->any);
|
|
if (LASSO_IS_IDWSF2_DISCO_SECURITY_CONTEXT (context)) {
|
|
lasso_foreach_full_begin(char*, textnode, it2, context->SecurityMechID);
|
|
if (lasso_strisequal(textnode,security_mech_id) || sech_mech_predicate(textnode)) {
|
|
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_DISCOVERY_HREF;
|
|
new_security_mech_id_declaration->ns_prefix = LASSO_IDWSF2_DISCOVERY_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) {
|
|
message(G_LOG_LEVEL_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 && lasso_strisequal(token->usage,usage)) {
|
|
if (LASSO_IS_NODE(token->any)) {
|
|
return (LassoNode*)token->any;
|
|
} else if (token->ref) {
|
|
message(G_LOG_LEVEL_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();
|
|
epr->Metadata = metadata;
|
|
|
|
/* 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:(element-type utf8): 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, GList *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_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);
|
|
lasso_assign_string(sec_token->usage, LASSO_IDWSF2_SEC_TOKEN_USAGE_SECURITY_TOKEN);
|
|
|
|
security_context = lasso_idwsf2_disco_security_context_new();
|
|
lasso_assign_list_of_strings(security_context->SecurityMechID,
|
|
security_mechanisms);
|
|
lasso_list_add_new_gobject(security_context->Token, sec_token);
|
|
lasso_list_add_new_gobject(metadata->any, security_context);
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
static GHashTable *_mapping = NULL;
|
|
|
|
static GHashTable *_get_mapping() {
|
|
if (_mapping == NULL) {
|
|
_mapping = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
|
|
}
|
|
return _mapping;
|
|
}
|
|
|
|
|
|
/**
|
|
* lasso_wsa_endpoint_reference_associate_service_to_type:
|
|
* @service_type_uri: a service type to associate
|
|
* @g_type: the type of the profile object handling this service type
|
|
*
|
|
* Associate a profile type to a service type.
|
|
*
|
|
* Return value: 0 if successful, an error code otherwise.
|
|
*/
|
|
int
|
|
lasso_wsa_endpoint_reference_associate_service_to_type(
|
|
const char *service_type_uri, GType g_type)
|
|
{
|
|
int rc = 0;
|
|
|
|
lasso_check_non_empty_string(service_type_uri);
|
|
if (! g_type_is_a(g_type, LASSO_TYPE_IDWSF2_PROFILE)) {
|
|
return LASSO_PARAM_ERROR_INVALID_VALUE;
|
|
}
|
|
g_hash_table_insert(_get_mapping(),
|
|
g_strdup(service_type_uri), (gpointer)g_type);
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* lasso_wsa_endpoint_reference_get_service:
|
|
* @epr: a #LassoWsAddrEndpointReference object
|
|
*
|
|
* Get a profile object able to communicate with the service represented by this EPR.
|
|
*
|
|
* Return object: a newly created #LassoIdWsf2Profile instance.
|
|
*/
|
|
LassoIdWsf2Profile *
|
|
lasso_wsa_endpoint_reference_get_service(
|
|
LassoWsAddrEndpointReference *epr)
|
|
{
|
|
GType type;
|
|
const char *service_type_uri;
|
|
|
|
if (! LASSO_IS_WSA_ENDPOINT_REFERENCE(epr))
|
|
return NULL;
|
|
|
|
service_type_uri = lasso_wsa_endpoint_reference_get_idwsf2_service_type(epr);
|
|
type = (GType)g_hash_table_lookup(_get_mapping(), service_type_uri);
|
|
if (type) {
|
|
LassoIdWsf2Profile *profile;
|
|
|
|
profile = (LassoIdWsf2Profile*)g_object_new(type, NULL);
|
|
lasso_idwsf2_profile_set_epr(profile, epr);
|
|
|
|
return profile;
|
|
}
|
|
return NULL;
|
|
}
|