summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-08-25 18:57:25 +0200
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-08-25 18:57:25 +0200
commit908d4288a0a7df793c104118dc921ba4b57a2bb8 (patch)
tree55658e5112a7a72b86a756367f8e3df5649c5778
parent5c85507ffd906e9a3f15b1206f9cc0e56bc8a207 (diff)
downloadlasso-908d4288a0a7df793c104118dc921ba4b57a2bb8.tar.gz
lasso-908d4288a0a7df793c104118dc921ba4b57a2bb8.tar.xz
lasso-908d4288a0a7df793c104118dc921ba4b57a2bb8.zip
[SAMLv2] rebuild specialized LassoProvider methods upon new endpoints storage
The new way of storing endpoints allows to keep ordering between endpoints with respect to the order of the index and isDefault field for indexed endpoint type, and to the XML node orders for other endpoints. It also simplifies the code.
-rw-r--r--lasso/saml-2.0/provider.c517
1 files changed, 239 insertions, 278 deletions
diff --git a/lasso/saml-2.0/provider.c b/lasso/saml-2.0/provider.c
index 65bd579b..b532259e 100644
--- a/lasso/saml-2.0/provider.c
+++ b/lasso/saml-2.0/provider.c
@@ -53,8 +53,6 @@ const char *profile_names[LASSO_MD_PROTOCOL_TYPE_LAST] = {
"AttributeService" /*AttributeAuthorityDescriptor*/
};
-static void add_assertion_consumer_url_to_list(gchar *key, G_GNUC_UNUSED gpointer value, GList **list);
-
static const char*
binding_uri_to_identifier(const char *uri)
{
@@ -74,23 +72,21 @@ binding_uri_to_identifier(const char *uri)
return NULL;
}
-static const char*
-identifier_to_binding_uri(const char *identifier)
+static LassoHttpMethod
+binding_uri_to_http_method(const char *uri)
{
- if (strcmp(identifier, "SOAP") == 0) {
- return LASSO_SAML2_METADATA_BINDING_SOAP;
- } else if (strcmp(identifier, "HTTP-Redirect") == 0) {
- return LASSO_SAML2_METADATA_BINDING_REDIRECT;
- } else if (strcmp(identifier, "HTTP-POST") == 0) {
- return LASSO_SAML2_METADATA_BINDING_POST;
- } else if (strcmp(identifier, "HTTP-Artifact") == 0) {
- return LASSO_SAML2_METADATA_BINDING_ARTIFACT;
- } else if (strcmp(identifier, "PAOS") == 0) {
- return LASSO_SAML2_METADATA_BINDING_PAOS;
- } else if (strcmp(identifier, "URI") == 0) {
- return LASSO_SAML2_METADATA_BINDING_URI;
+ if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_SOAP) == 0) {
+ return LASSO_HTTP_METHOD_SOAP;
+ } else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_REDIRECT) == 0) {
+ return LASSO_HTTP_METHOD_REDIRECT;
+ } else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_POST) == 0) {
+ return LASSO_HTTP_METHOD_NONE;
+ } else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_ARTIFACT) == 0) {
+ return LASSO_HTTP_METHOD_ARTIFACT_GET;
+ } else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
+ return LASSO_HTTP_METHOD_PAOS;
}
- return NULL;
+ return LASSO_HTTP_METHOD_NONE;
}
static gboolean
@@ -127,6 +123,87 @@ xsdIsFalse(xmlChar *value)
return FALSE;
}
+static gboolean
+xsdUnsignedShortParse(xmlChar *value, int *out) {
+ int l = strtol((char*)value, NULL, 10);
+
+ if (((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
+ errno == EINVAL || l < 0 || l >= 65535) {
+ return FALSE;
+ }
+ *out = l;
+ return TRUE;
+}
+
+static void
+load_endpoint_type2(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole role, int *counter)
+{
+ xmlChar *binding = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_BINDING);
+ xmlChar *location = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_LOCATION);
+ xmlChar *response_location = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_RESPONSE_LOCATION);
+ xmlChar *index = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_INDEX);
+ xmlChar *isDefault = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_ISDEFAULT);
+ gboolean indexed_endpoint = FALSE;
+ int idx = *counter++;
+ gboolean is_default = FALSE;
+ EndpointType *endpoint_type;
+
+ if (! binding || ! location) {
+ warning("Invalid endpoint node %s", (char*) xmlnode->name);
+ goto cleanup;
+ }
+ indexed_endpoint = checkSaml2MdNode(xmlnode, LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE);
+ if (indexed_endpoint) {
+ if (! xsdUnsignedShortParse(index, &idx)) {
+ warning("Invalid AssertionConsumerService, no index set");
+ goto cleanup;
+ }
+ is_default = xsdIsTrue(isDefault);
+ }
+ endpoint_type = g_new0(EndpointType, 1);
+ endpoint_type->kind = g_strdup((char*)xmlnode->name);
+ endpoint_type->binding = g_strdup((char*)binding);
+ endpoint_type->url = g_strdup((char*)location);
+ endpoint_type->return_url = g_strdup((char*)response_location);
+ endpoint_type->role = role;
+ endpoint_type->index = idx;
+ endpoint_type->is_default = is_default;
+ lasso_list_add(provider->private_data->endpoints, (void*)endpoint_type);
+
+cleanup:
+ lasso_release_xml_string(binding);
+ lasso_release_xml_string(location);
+ lasso_release_xml_string(response_location);
+ lasso_release_xml_string(isDefault);
+ lasso_release_xml_string(index);
+}
+
+static gint
+compare_endpoint_type(const EndpointType *a, const EndpointType *b) {
+ int c;
+
+ if (a->role < b->role)
+ return -1;
+ if (a->role > b->role)
+ return +1;
+ c = g_strcmp0(a->kind, b->kind);
+ if (c != 0)
+ return c;
+ c = g_strcmp0(a->binding, b->binding);
+ if (c != 0)
+ return c;
+ if (a->is_default && ! b->is_default)
+ return -1;
+ if (! a->is_default && b->is_default)
+ return +1;
+ if (a->index < b->index)
+ return -1;
+ if (a->index > b->index)
+ return +1;
+ return 0;
+}
+
+
static void
load_endpoint_type(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole role)
{
@@ -141,7 +218,7 @@ load_endpoint_type(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole
binding_s = binding_uri_to_identifier((char*)binding);
if (! binding_s) {
- message(G_LOG_LEVEL_CRITICAL, "XXX: unknown binding: %s", binding);
+ critical("XXX: unknown binding: %s", binding);
goto cleanup;
}
@@ -259,6 +336,7 @@ load_descriptor(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole rol
xmlChar *value;
LassoProviderPrivate *pdata = provider->private_data;
char *token, *saveptr;
+ int counter = 0;
/* check protocol support enumeration */
value = getSaml2MdProp(xmlnode,
@@ -290,6 +368,7 @@ load_descriptor(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole rol
attribute);
} else if (hasSaml2MdProp(t, LASSO_SAML2_METADATA_ATTRIBUTE_BINDING)) {
load_endpoint_type(t, provider, role);
+ load_endpoint_type2(t, provider, role, &counter);
} else {
value = xmlNodeGetContent(t);
_lasso_provider_add_metadata_value_for_role(provider, role, (char*)t->name,
@@ -298,6 +377,8 @@ load_descriptor(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole rol
}
t = xmlSecGetNextElementNode(t->next);
}
+ provider->private_data->endpoints = g_list_sort(provider->private_data->endpoints,
+ (GCompareFunc) compare_endpoint_type);
for (i = 0; descriptor_attrs[i]; i++) {
value = getSaml2MdProp(xmlnode, descriptor_attrs[i]);
if (value == NULL) {
@@ -403,226 +484,141 @@ lasso_saml20_provider_load_metadata(LassoProvider *provider, xmlNode *root_node)
}
LassoHttpMethod
-lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
+lasso_saml20_provider_get_first_http_method(G_GNUC_UNUSED LassoProvider *provider,
LassoProvider *remote_provider, LassoMdProtocolType protocol_type)
{
- LassoHttpMethod method = LASSO_HTTP_METHOD_NONE;
- LassoProviderRole our_role = LASSO_PROVIDER_ROLE_SP;
- int i;
- const char *possible_bindings[] = {
- "HTTP-POST",
- "HTTP-Redirect",
- "HTTP-Artifact",
- "SOAP",
- "PAOS",
- NULL
- };
- LassoHttpMethod method_bindings[] = {
- LASSO_HTTP_METHOD_POST,
- LASSO_HTTP_METHOD_REDIRECT,
- LASSO_HTTP_METHOD_ARTIFACT_GET,
- LASSO_HTTP_METHOD_SOAP,
- LASSO_HTTP_METHOD_PAOS
- };
+ GList *t = NULL;
+ const char *kind = NULL;
+ LassoHttpMethod result = LASSO_HTTP_METHOD_NONE;
+
+ if (protocol_type < LASSO_MD_PROTOCOL_TYPE_LAST) {
+ kind = profile_names[protocol_type];
+ }
+ if (! kind) {
+ warning("Could not find a first http method for protocol type %u", protocol_type);
+ return LASSO_HTTP_METHOD_NONE;
+ }
- switch (remote_provider->role) {
- case LASSO_PROVIDER_ROLE_IDP:
- our_role = LASSO_PROVIDER_ROLE_SP;
- break;
- case LASSO_PROVIDER_ROLE_SP:
- our_role = LASSO_PROVIDER_ROLE_IDP;
- break;
- default:
- return LASSO_HTTP_METHOD_NONE;
- }
- for (i=0; possible_bindings[i] && method == LASSO_HTTP_METHOD_NONE; i++) {
- char *s;
- const GList *l1, *l2;
-
- s = g_strdup_printf("%s %s",
- profile_names[protocol_type],
- possible_bindings[i]);
- l1 = lasso_provider_get_metadata_list_for_role(provider, our_role, s);
- l2 = lasso_provider_get_metadata_list(remote_provider, s);
- if (l1 && l2) {
- method = method_bindings[i];
+ lasso_foreach(t, remote_provider->private_data->endpoints) {
+ EndpointType *endpoint_type = (EndpointType*)t->data;
+ if (endpoint_type && g_strcmp0(endpoint_type->kind, kind) == 0) {
+ result = binding_uri_to_http_method(endpoint_type->binding);
+ if (result) break;
}
}
- return method;
+ return result;
}
gboolean
-lasso_saml20_provider_check_assertion_consumer_service_url(LassoProvider *provider, const gchar *url, const gchar *binding)
+lasso_saml20_provider_accept_http_method(G_GNUC_UNUSED LassoProvider *provider, LassoProvider *remote_provider,
+ LassoMdProtocolType protocol_type, LassoHttpMethod http_method,
+ G_GNUC_UNUSED gboolean initiate_profile)
{
- GHashTable *descriptor;
- GList *l = NULL, *r = NULL, *candidate = NULL;
- char *name;
- const char *binding_s = NULL;
- int lname;
-
- descriptor = provider->private_data->Descriptors;
- if (descriptor == NULL || url == NULL || binding == NULL)
- return FALSE;
-
- binding_s = binding_uri_to_identifier(binding);
- if (binding_s == NULL) {
- return FALSE;
+ GList *t = NULL;
+ const char *kind = NULL;
+
+ if (protocol_type < LASSO_MD_PROTOCOL_TYPE_LAST) {
+ kind = profile_names[protocol_type];
+ }
+ if (! kind) {
+ warning("Could not find a first http method for protocol type %u", protocol_type);
+ return LASSO_HTTP_METHOD_NONE;
}
- g_hash_table_foreach(descriptor,
- (GHFunc)add_assertion_consumer_url_to_list,
- &r);
-
- name = g_strdup_printf(LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
- " %s ", binding_s);
- lname = strlen(name);
- for (l = r; l; l = g_list_next(l)) {
- char *b = l->data;
- if (strncmp(name, b, lname) == 0) {
- candidate = lasso_provider_get_metadata_list_for_role(provider, LASSO_PROVIDER_ROLE_SP, b);
- if (candidate && candidate->data && strcmp(candidate->data, url) == 0)
- break;
- else
- candidate = NULL;
+ lasso_foreach(t, remote_provider->private_data->endpoints) {
+ EndpointType *endpoint_type = (EndpointType*)t->data;
+ if (endpoint_type && endpoint_type->role == remote_provider->role &&
+ g_strcmp0(endpoint_type->kind, kind) == 0) {
+ if (binding_uri_to_http_method(endpoint_type->binding) == http_method) {
+ return TRUE;
+ }
}
}
- lasso_release(name);
- lasso_release_list(r);
- if (candidate)
- return TRUE;
- else
- return FALSE;
+ return FALSE;
}
-gchar*
-lasso_saml20_provider_get_assertion_consumer_service_url(LassoProvider *provider,
- int service_id)
+gboolean
+lasso_saml20_provider_check_assertion_consumer_service_url(LassoProvider *provider, const gchar *url, const gchar *binding)
{
- GList *l = NULL;
- char *sid;
- char *name;
- const char *possible_bindings[] = {
- "HTTP-Artifact",
- "HTTP-POST",
- NULL
- };
- int i;
-
- if (service_id == -1) {
- sid = g_strdup(provider->private_data->default_assertion_consumer);
- } else {
- sid = g_strdup_printf("%d", service_id);
- }
-
- for (i=0; possible_bindings[i]; i++) {
- name = g_strdup_printf(LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
- " %s %s",
- possible_bindings[i], sid);
- l = lasso_provider_get_metadata_list_for_role(provider,
- LASSO_PROVIDER_ROLE_SP,
- name);
- lasso_release_string(name);
- if (l != NULL)
- break;
+ GList *t = NULL;
+
+ lasso_foreach (provider->private_data->endpoints, t) {
+ EndpointType *endpoint_type = (EndpointType*) t->data;
+ if (endpoint_type && endpoint_type->role == LASSO_PROVIDER_ROLE_SP
+ && g_strcmp0(endpoint_type->url, url) == 0
+ && g_strcmp0(endpoint_type->binding, binding) == 0)
+ {
+ return TRUE;
+ }
}
- lasso_release_string(sid);
- if (l)
- return g_strdup(l->data);
- return NULL;
+ return FALSE;
}
-#define ACS_KEY "sp " LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
+static const char *supported_assertion_consumer_bindings[] = { LASSO_SAML2_METADATA_BINDING_POST,
+ LASSO_SAML2_METADATA_BINDING_ARTIFACT, NULL };
-static void
-add_assertion_consumer_url_to_list(gchar *key, G_GNUC_UNUSED gpointer value, GList **list)
-{
- if (strncmp(key, ACS_KEY, sizeof(ACS_KEY)-1) == 0) {
- lasso_list_add_new_string(*list, key);
+static gboolean match_any(const char *key, const char *array[]) {
+ const char **t = array;
+
+ while (*t) {
+ if (g_strcmp0(key, *t) == 0) {
+ return TRUE;
+ }
+ t++;
}
+ return FALSE;
}
-struct HelperBindingByUrl {
- const char *binding;
- const char *url;
-};
-
-void
-helper_binding_by_url(char *key, GList *value, struct HelperBindingByUrl *data)
+static EndpointType *
+lasso_saml20_provider_get_assertion_consumer_service(LassoProvider *provider, int service_id)
{
- if (strncmp(key, ACS_KEY, sizeof(ACS_KEY)-1) != 0) {
- return;
- }
-
- if (data->binding == NULL && g_list_find_custom(value, data->url, (GCompareFunc)g_strcmp0) != NULL) {
- char *end;
- // URL was found for the first time
- key += sizeof(ACS_KEY);
- end = strchr(key, ' ');
- if (end) {
- key = g_strndup(key, (ptrdiff_t)(end-key));
- data->binding = identifier_to_binding_uri(key);
- lasso_release(key);
- } else {
- data->binding = identifier_to_binding_uri(key);
+ const char *kind = LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE;
+ GList *t = NULL;
+ EndpointType *result = NULL;
+
+ if (service_id != -1) {
+ lasso_foreach(t, provider->private_data->endpoints) {
+ EndpointType *endpoint_type = (EndpointType*) t->data;
+ if (! endpoint_type)
+ continue;
+ if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
+ g_strcmp0(endpoint_type->kind, kind) == 0 &&
+ endpoint_type->index == service_id)
+ {
+ result = endpoint_type;
+ break;
+ }
+ }
+ } else { /* lookup a default supported endpoint type */
+ lasso_foreach(t, provider->private_data->endpoints) {
+ EndpointType *endpoint_type = (EndpointType*) t->data;
+ if (! endpoint_type)
+ continue;
+ if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
+ g_strcmp0(endpoint_type->kind, kind) == 0 &&
+ match_any(endpoint_type->binding,
+ supported_assertion_consumer_bindings))
+ {
+ result = endpoint_type;
+ break;
+ }
}
}
-
+ return result;
}
-const gchar*
-lasso_saml20_provider_get_assertion_consumer_service_binding_by_url(LassoProvider *provider, const char *url)
-{
- struct HelperBindingByUrl _helper_binding_by_url = { .binding = NULL, .url = url };
-
- g_hash_table_foreach(provider->private_data->Descriptors, (GHFunc)helper_binding_by_url,
- &_helper_binding_by_url);
-
- return _helper_binding_by_url.binding;
-}
gchar*
-lasso_saml20_provider_get_assertion_consumer_service_url_by_binding(LassoProvider *provider,
- const gchar *binding)
+lasso_saml20_provider_get_assertion_consumer_service_url(LassoProvider *provider,
+ int service_id)
{
- GHashTable *descriptor;
- GList *l = NULL, *r = NULL;
- char *name;
- const char *binding_s = NULL;
- int lname;
-
- descriptor = provider->private_data->Descriptors;
- if (descriptor == NULL)
- return NULL;
-
- binding_s = binding_uri_to_identifier(binding);
- if (binding_s == NULL) {
- return NULL;
- }
-
- g_hash_table_foreach(descriptor,
- (GHFunc)add_assertion_consumer_url_to_list,
- &r);
-
- name = g_strdup_printf("sp "
- LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
- " %s ", binding_s);
- lname = strlen(name);
- for (l = r; l; l = g_list_next(l)) {
- char *b = l->data;
- if (strncmp(name, b, lname) == 0) {
- l = g_hash_table_lookup(descriptor, b);
- break;
- }
- }
- lasso_release_string(name);
- lasso_release_list(r);
-
- if (l) {
- return g_strdup(l->data);
+ EndpointType *endpoint_type = lasso_saml20_provider_get_assertion_consumer_service(provider, service_id);
+ if (endpoint_type)
+ {
+ return g_strdup(endpoint_type->url);
}
-
return NULL;
}
@@ -630,88 +626,53 @@ gchar*
lasso_saml20_provider_get_assertion_consumer_service_binding(LassoProvider *provider,
int service_id)
{
- GHashTable *descriptor;
- GList *l = NULL;
- char *sid;
- char *name;
- char *binding = NULL;
- const char *possible_bindings[] = {
- "HTTP-POST",
- "HTTP-Redirect",
- "HTTP-Artifact",
- "SOAP",
- NULL
- };
- int i;
-
- if (service_id == -1) {
- sid = g_strdup(provider->private_data->default_assertion_consumer);
- } else {
- sid = g_strdup_printf("%d", service_id);
- }
- descriptor = provider->private_data->Descriptors;
- if (descriptor == NULL)
- return NULL;
-
- for (i=0; possible_bindings[i]; i++) {
- name = g_strdup_printf(LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
- " %s %s",
- possible_bindings[i], sid);
- l = lasso_provider_get_metadata_list_for_role(provider, LASSO_PROVIDER_ROLE_SP, name);
- lasso_release_string(name);
- if (l != NULL) {
- binding = g_strdup(possible_bindings[i]);
- break;
- }
+ EndpointType *endpoint_type = lasso_saml20_provider_get_assertion_consumer_service(provider, service_id);
+ if (endpoint_type)
+ {
+ return g_strdup(binding_uri_to_identifier(endpoint_type->binding));
}
- lasso_release_string(sid);
- return binding;
+ return NULL;
}
-gboolean
-lasso_saml20_provider_accept_http_method(LassoProvider *provider, LassoProvider *remote_provider,
- LassoMdProtocolType protocol_type, LassoHttpMethod http_method,
- gboolean initiate_profile)
+const gchar*
+lasso_saml20_provider_get_assertion_consumer_service_binding_by_url(LassoProvider *provider, const char *url)
{
- char *protocol_profile;
- static const char *http_methods[] = {
- NULL,
- NULL,
- NULL,
- NULL,
- "HTTP-POST",
- "HTTP-Redirect",
- "SOAP",
- "HTTP-Artifact",
- "HTTP-Artifact",
- NULL
- };
- gboolean rc = FALSE;
- LassoProviderRole initiating_role;
+ const char *kind = LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE;
+ GList *t = NULL;
- initiating_role = remote_provider->role;
- if (remote_provider->role == LASSO_PROVIDER_ROLE_SP) {
- provider->role = LASSO_PROVIDER_ROLE_IDP;
- }
- if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP) {
- provider->role = LASSO_PROVIDER_ROLE_SP;
- }
- if (initiate_profile)
- initiating_role = provider->role;
-
- /* exclude bad input */
- if (http_method > (int)G_N_ELEMENTS(http_methods) || http_method < 0 || http_methods[http_method+1] == NULL) {
- return FALSE;
+ lasso_foreach(t, provider->private_data->endpoints) {
+ EndpointType *endpoint_type = (EndpointType*) t->data;
+ if (! endpoint_type)
+ continue;
+ if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
+ g_strcmp0(endpoint_type->kind, kind) == 0 &&
+ g_strcmp0(endpoint_type->url, url) == 0)
+ {
+ return endpoint_type->binding;
+ }
}
+ return NULL;
+}
- protocol_profile = g_strdup_printf("%s %s", profile_names[protocol_type],
- http_methods[http_method+1]);
+gchar*
+lasso_saml20_provider_get_assertion_consumer_service_url_by_binding(LassoProvider *provider,
+ const gchar *binding)
+{
+ const char *kind = LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE;
+ GList *t = NULL;
- /* just check if remote provider can receive the request, remote provider will have to check
- * how to return the response itself */
- rc = (lasso_provider_get_metadata_list(remote_provider, protocol_profile) != NULL);
- lasso_release_string(protocol_profile);
- return rc;
+ lasso_foreach(t, provider->private_data->endpoints) {
+ EndpointType *endpoint_type = (EndpointType*) t->data;
+ if (! endpoint_type)
+ continue;
+ if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
+ g_strcmp0(endpoint_type->kind, kind) == 0 &&
+ g_strcmp0(endpoint_type->binding, binding) == 0)
+ {
+ return endpoint_type->url;
+ }
+ }
+ return NULL;
}
/**