[core] make lasso_server_load_metadata load any metadata file
The new code can load metadata file with a EntityDescriptor root node, and with nested EntitiesDescriptor. Idea and prototype by Olav Morken.
This commit is contained in:
parent
31a623aeee
commit
cad3d305a9
|
@ -301,6 +301,8 @@ lasso_strerror(int error_code)
|
|||
return "Failed to add new provider (protocol mismatch). It means that you tried to add a provider supporting a protocol imcompatible with the protocol declared for your #LassoServer, for example metadata for ID-FF 1.2 with metadata for SAML 2.0.";
|
||||
case LASSO_SERVER_ERROR_INVALID_XML:
|
||||
return "Parsed XML is invalid.";
|
||||
case LASSO_SERVER_ERROR_NO_PROVIDER_LOADED:
|
||||
return "When loading a metadata file it indicates that no provider could be loaded. It could be because the file is not well formed, or because there is no provider for the role sought.";
|
||||
case LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND:
|
||||
return "The identifier of a provider is unknown to #LassoServer. To register a provider in a #LassoServer object, you must use the methods lasso_server_add_provider() or lasso_server_add_provider_from_buffer().";
|
||||
case LASSO_SERVER_ERROR_SET_ENCRYPTION_PRIVATE_KEY_FAILED:
|
||||
|
|
|
@ -263,6 +263,15 @@ LASSO_EXPORT const char* lasso_strerror(int error_code);
|
|||
* Parsed XML is invalid.
|
||||
*/
|
||||
#define LASSO_SERVER_ERROR_INVALID_XML -205
|
||||
/**
|
||||
* LASSO_SERVER_ERROR_NO_PROVIDER_LOADED
|
||||
*
|
||||
* When loading a metadata file it indicates that no provider could be loaded.
|
||||
* It could be because the file is not well formed, or because there is no provider for the
|
||||
* role sought.
|
||||
*
|
||||
*/
|
||||
#define LASSO_SERVER_ERROR_NO_PROVIDER_LOADED 206
|
||||
|
||||
/* Single Logout */
|
||||
/**
|
||||
|
|
|
@ -803,7 +803,8 @@ lasso_server_load_metadata(LassoServer *server, LassoProviderRole role, const gc
|
|||
EMPTY_URI, &uri_references));
|
||||
}
|
||||
if (lasso_strisequal((char*)root->ns->href, LASSO_SAML2_METADATA_HREF)) {
|
||||
lasso_check_good_rc(lasso_saml20_server_load_federation(server, role, root, blacklisted_entity_ids, loaded_entity_ids));
|
||||
lasso_check_good_rc(lasso_saml20_server_load_metadata(server, role, root,
|
||||
blacklisted_entity_ids, loaded_entity_ids));
|
||||
} else {
|
||||
goto_cleanup_with_rc(LASSO_ERROR_UNIMPLEMENTED);
|
||||
}
|
||||
|
|
|
@ -102,51 +102,113 @@ _lasso_test_idp_descriptor(xmlNode *node) {
|
|||
BAD_CAST LASSO_SAML2_METADATA_HREF) != NULL;
|
||||
}
|
||||
|
||||
lasso_error_t
|
||||
lasso_saml20_server_load_federation(LassoServer *server, LassoProviderRole role, xmlNode *root_node, GList *blacklisted_entity_ids, GList **loaded_entity_ids)
|
||||
static lasso_error_t
|
||||
lasso_saml20_server_load_metadata_entity(LassoServer *server, LassoProviderRole role,
|
||||
xmlNode *entity, GList *blacklisted_entity_ids, GList **loaded_end)
|
||||
{
|
||||
LassoProvider *provider = NULL;
|
||||
|
||||
if (role == LASSO_PROVIDER_ROLE_IDP && ! _lasso_test_idp_descriptor(entity)) {
|
||||
return 0;
|
||||
}
|
||||
if (role == LASSO_PROVIDER_ROLE_SP && ! _lasso_test_sp_descriptor(entity)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
provider = lasso_provider_new_from_xmlnode(role, entity);
|
||||
if (provider) {
|
||||
char *name = g_strdup(provider->ProviderID);
|
||||
|
||||
if (g_list_find_custom(blacklisted_entity_ids, name,
|
||||
(GCompareFunc) g_strcmp0)) {
|
||||
lasso_release_gobject(provider);
|
||||
return LASSO_SERVER_ERROR_NO_PROVIDER_LOADED;
|
||||
}
|
||||
if (*loaded_end) {
|
||||
GList *l = *loaded_end;
|
||||
l->next = g_new0(GList, 1);
|
||||
l->next->data = g_strdup(name);
|
||||
*loaded_end = l->next;
|
||||
}
|
||||
g_hash_table_insert(server->providers, name, provider);
|
||||
return 0;
|
||||
} else {
|
||||
return LASSO_SERVER_ERROR_NO_PROVIDER_LOADED;
|
||||
}
|
||||
}
|
||||
|
||||
static lasso_error_t lasso_saml20_server_load_metadata_child(LassoServer *server,
|
||||
LassoProviderRole role, xmlNode *child, GList *blacklisted_entity_ids,
|
||||
GList **loaded_end);
|
||||
|
||||
static lasso_error_t
|
||||
lasso_saml20_server_load_metadata_entities(LassoServer *server, LassoProviderRole role, xmlNode *entities,
|
||||
GList *blacklisted_entity_ids, GList **loaded_end)
|
||||
{
|
||||
xmlNode *child;
|
||||
lasso_error_t rc = 0;
|
||||
GList loaded = { .data = NULL, .next = NULL };
|
||||
GList *loaded_end = &loaded;
|
||||
gboolean at_least_one = FALSE;
|
||||
|
||||
child = xmlSecGetNextElementNode(root_node->children);
|
||||
/* first parse the providers... */
|
||||
child = xmlSecGetNextElementNode(entities->children);
|
||||
while (child) {
|
||||
LassoProvider *provider = NULL;
|
||||
lasso_error_t rc = 0;
|
||||
|
||||
if (! xmlSecCheckNodeName(child,
|
||||
BAD_CAST LASSO_SAML2_METADATA_ELEMENT_ENTITY_DESCRIPTOR,
|
||||
BAD_CAST LASSO_SAML2_METADATA_HREF)) {
|
||||
goto next;
|
||||
rc = lasso_saml20_server_load_metadata_child(server, role, child,
|
||||
blacklisted_entity_ids, loaded_end);
|
||||
if (rc == 0) {
|
||||
at_least_one = TRUE;
|
||||
}
|
||||
if (role == LASSO_PROVIDER_ROLE_IDP && ! _lasso_test_idp_descriptor(child)) {
|
||||
goto next;
|
||||
}
|
||||
if (role == LASSO_PROVIDER_ROLE_SP && ! _lasso_test_sp_descriptor(child)) {
|
||||
goto next;
|
||||
}
|
||||
|
||||
provider = lasso_provider_new_from_xmlnode(role, child);
|
||||
if (provider) {
|
||||
char *name = g_strdup(provider->ProviderID);
|
||||
|
||||
if (g_list_find_custom(blacklisted_entity_ids, name,
|
||||
(GCompareFunc) g_strcmp0)) {
|
||||
lasso_release_gobject(provider);
|
||||
goto next;
|
||||
}
|
||||
if (loaded_entity_ids) {
|
||||
loaded_end->next = g_new0(GList, 1);
|
||||
loaded_end->next->data = g_strdup(name);
|
||||
loaded_end = loaded_end->next;
|
||||
}
|
||||
g_hash_table_insert(server->providers, name, provider);
|
||||
}
|
||||
next:
|
||||
child = xmlSecGetNextElementNode(child->next);
|
||||
}
|
||||
return at_least_one ? 0 : LASSO_SERVER_ERROR_NO_PROVIDER_LOADED;
|
||||
}
|
||||
|
||||
static lasso_error_t
|
||||
lasso_saml20_server_load_metadata_child(LassoServer *server, LassoProviderRole role, xmlNode *child,
|
||||
GList *blacklisted_entity_ids, GList **loaded_end)
|
||||
{
|
||||
if (xmlSecCheckNodeName(child,
|
||||
BAD_CAST LASSO_SAML2_METADATA_ELEMENT_ENTITY_DESCRIPTOR,
|
||||
BAD_CAST LASSO_SAML2_METADATA_HREF)) {
|
||||
return lasso_saml20_server_load_metadata_entity(server, role, child,
|
||||
blacklisted_entity_ids, loaded_end);
|
||||
} else if (xmlSecCheckNodeName(child,
|
||||
BAD_CAST LASSO_SAML2_METADATA_ELEMENT_ENTITIES_DESCRIPTOR,
|
||||
BAD_CAST LASSO_SAML2_METADATA_HREF)) {
|
||||
return lasso_saml20_server_load_metadata_entities(server, role, child,
|
||||
blacklisted_entity_ids, loaded_end);
|
||||
}
|
||||
return LASSO_SERVER_ERROR_INVALID_XML;
|
||||
}
|
||||
|
||||
/**
|
||||
* lasso_saml20_server_load_metadata:
|
||||
* @server: a #LassoServer object
|
||||
* @role: the role of providers to load
|
||||
* @root_node: the root node a SAML 2.0 metadata file
|
||||
* @blacklisted_entity_ids: a list of entity IDs of provider to skip
|
||||
* @loaded_entity_ids: an out parameter to return the list of the loaded providers entity IDs
|
||||
*
|
||||
* Load the SAML 2.0 providers present in the given metadata as pointed to by the @root_node
|
||||
* parameter. If at least one provider is loaded the call is deemed successful.
|
||||
*
|
||||
* Return value: 0 if at least one provider has been loaded, LASSO_SERVER_ERROR_NO_PROVIDER_LOADED
|
||||
* otherwise.
|
||||
*/
|
||||
lasso_error_t
|
||||
lasso_saml20_server_load_metadata(LassoServer *server, LassoProviderRole role, xmlNode *root_node,
|
||||
GList *blacklisted_entity_ids, GList **loaded_entity_ids)
|
||||
{
|
||||
lasso_error_t rc = 0;
|
||||
GList loaded = { .data = NULL, .next = NULL };
|
||||
GList *loaded_end = NULL;
|
||||
|
||||
if (loaded_entity_ids) {
|
||||
loaded_end = &loaded;
|
||||
}
|
||||
rc = lasso_saml20_server_load_metadata_child(server, role,
|
||||
root_node, blacklisted_entity_ids, &loaded_end);
|
||||
if (loaded_entity_ids) {
|
||||
lasso_release_list_of_strings(*loaded_entity_ids);
|
||||
*loaded_entity_ids = loaded.next;
|
||||
}
|
||||
return rc;
|
||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
|||
#include "../id-ff/server.h"
|
||||
|
||||
int lasso_saml20_server_load_affiliation(LassoServer *server, xmlNode *node);
|
||||
lasso_error_t lasso_saml20_server_load_federation(LassoServer *server, LassoProviderRole role,
|
||||
lasso_error_t lasso_saml20_server_load_metadata(LassoServer *server, LassoProviderRole role,
|
||||
xmlNode *root_node, GList *blacklisted_entity_ids, GList **loaded_entity_ids);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue