summaryrefslogtreecommitdiffstats
path: root/auth_mellon_config.c
diff options
context:
space:
mode:
authormanu@netbsd.org <manu@netbsd.org@a716ebb1-153a-0410-b759-cfb97c6a1b53>2009-05-12 15:28:49 +0000
committermanu@netbsd.org <manu@netbsd.org@a716ebb1-153a-0410-b759-cfb97c6a1b53>2009-05-12 15:28:49 +0000
commit4c740a21c1f88bcc941f355fd52877e0666d05e0 (patch)
treeaaf51cfc0c47c7999d960846a87128bb58038d0e /auth_mellon_config.c
parent6b2fb648fff2828c093db414cd8f00d8624af966 (diff)
downloadmod_auth_mellon-4c740a21c1f88bcc941f355fd52877e0666d05e0.tar.gz
mod_auth_mellon-4c740a21c1f88bcc941f355fd52877e0666d05e0.tar.xz
mod_auth_mellon-4c740a21c1f88bcc941f355fd52877e0666d05e0.zip
- Support for multiple IdP
- IdP discovery service - add a dimple built-in IdP discovery mechanism: send HTTP GET on ProviderID URL. If we get HTTP 200, the IdP is selected git-svn-id: https://modmellon.googlecode.com/svn/trunk@44 a716ebb1-153a-0410-b759-cfb97c6a1b53
Diffstat (limited to 'auth_mellon_config.c')
-rw-r--r--auth_mellon_config.c123
1 files changed, 116 insertions, 7 deletions
diff --git a/auth_mellon_config.c b/auth_mellon_config.c
index 767663f..6e805e1 100644
--- a/auth_mellon_config.c
+++ b/auth_mellon_config.c
@@ -83,6 +83,103 @@ static const char *am_set_filestring_slot(cmd_parms *cmd,
}
+/* This function extracts an IdP ProviderID from metadata
+ *
+ * Parameters:
+ * apr_pool_t *p Pool to allocate temporary items from.
+ * server_rec *s The server.
+ * const char *file File containing metadata.
+ * const char **provider The providerID
+ *
+ * Returns:
+ * NULL on success or an error string on failure.
+ *
+ */
+static const char *am_get_proovider_id(apr_pool_t *p,
+ server_rec *s,
+ const char *file,
+ const char **provider)
+{
+ char *data;
+ apr_xml_parser *xp;
+ apr_xml_doc *xd;
+ apr_xml_attr *xa;
+ char error[1024];
+
+ *provider = NULL;
+
+ /*
+ * Get the data
+ */
+ if ((data = am_getfile(p, s, file)) == NULL)
+ return apr_psprintf(p, "Cannot read file %s", file);
+
+ /*
+ * Parse
+ */
+ xp = apr_xml_parser_create(p);
+ if (apr_xml_parser_feed(xp, data, strlen(data)) != 0)
+ return apr_psprintf(p, "Cannot parse %s: %s", file,
+ apr_xml_parser_geterror(xp, error, sizeof(error)));
+
+ if (apr_xml_parser_done(xp, &xd) != 0)
+ return apr_psprintf(p, "Parse error %s: %s", file,
+ apr_xml_parser_geterror(xp, error, sizeof(error)));
+
+ /*
+ * Extract /EntityDescriptor@EntityID
+ */
+ if (strcasecmp(xd->root->name, "EntityDescriptor") != 0)
+ return apr_psprintf(p, "<EntityDescriptor> is not root in %s", file);
+
+ for (xa = xd->root->attr; xa; xa = xa->next)
+ if (strcasecmp(xa->name, "entityID") == 0)
+ break;
+
+ if (xa == NULL)
+ return apr_psprintf(p, "entityID not found in %s", file);
+
+ *provider = xa->value;
+ return NULL;
+}
+
+/* This function handles configuration directives which set an
+ * idp related slot in the module configuration.
+ *
+ * Parameters:
+ * cmd_parms *cmd The command structure for this configuration
+ * directive.
+ * void *struct_ptr Pointer to the current directory configuration.
+ * NULL if we are not in a directory configuration.
+ * const char *arg The string argument following this configuration
+ * directive in the configuraion file.
+ *
+ * Returns:
+ * NULL on success or an error string on failure.
+ */
+static const char *ap_set_idp_string_slot(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg)
+{
+ server_rec *s = cmd->server;
+ apr_pool_t *pconf = s->process->pconf;
+ am_dir_cfg_rec *cfg = (am_dir_cfg_rec *)struct_ptr;
+ const char *error;
+ const char *provider_id;
+
+ if ((error = am_get_proovider_id(cmd->pool, s,
+ arg, &provider_id)) != NULL)
+ return apr_psprintf(cmd->pool, "%s - %s", cmd->cmd->name, error);
+
+ apr_hash_set(cfg->idp_metadata_files,
+ apr_pstrdup(pconf, provider_id),
+ APR_HASH_KEY_STRING,
+ apr_pstrdup(pconf, arg));
+
+ return NULL;
+}
+
+
/* This function handles configuration directives which set a string
* slot in the module configuration.
*
@@ -431,8 +528,8 @@ const command_rec auth_mellon_commands[] = {
),
AP_INIT_TAKE1(
"MellonIdPMetadataFile",
- ap_set_string_slot,
- (void *)APR_OFFSETOF(am_dir_cfg_rec, idp_metadata_file),
+ ap_set_idp_string_slot,
+ NULL,
OR_AUTHCFG,
"Full path to xml metadata file for the IdP."
),
@@ -459,6 +556,13 @@ const command_rec auth_mellon_commands[] = {
" Default value is \"/\"."
),
AP_INIT_TAKE1(
+ "MellonDiscoveryURL",
+ ap_set_string_slot,
+ (void *)APR_OFFSETOF(am_dir_cfg_rec, discovery_url),
+ OR_AUTHCFG,
+ "The URL of IdP discovery service. Default is unset."
+ ),
+ AP_INIT_TAKE1(
"MellonEndpointPath",
am_set_endpoint_path,
NULL,
@@ -506,11 +610,11 @@ void *auth_mellon_dir_config(apr_pool_t *p, char *d)
dir->sp_metadata_file = NULL;
dir->sp_private_key_file = NULL;
dir->sp_cert_file = NULL;
- dir->idp_metadata_file = NULL;
+ dir->idp_metadata_files = apr_hash_make(p);
dir->idp_public_key_file = NULL;
dir->idp_ca_file = NULL;
dir->login_path = default_login_path;
-
+ dir->discovery_url = NULL;
apr_thread_mutex_create(&dir->server_mutex, APR_THREAD_MUTEX_DEFAULT, p);
@@ -602,9 +706,10 @@ void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add)
add_cfg->sp_cert_file :
base_cfg->sp_cert_file);
- new_cfg->idp_metadata_file = (add_cfg->idp_metadata_file ?
- add_cfg->idp_metadata_file :
- base_cfg->idp_metadata_file);
+ new_cfg->idp_metadata_files = apr_hash_copy(p,
+ (apr_hash_count(add_cfg->idp_metadata_files) > 0) ?
+ add_cfg->idp_metadata_files :
+ base_cfg->idp_metadata_files);
new_cfg->idp_public_key_file = (add_cfg->idp_public_key_file ?
add_cfg->idp_public_key_file :
@@ -618,6 +723,10 @@ void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add)
add_cfg->login_path :
base_cfg->login_path);
+ new_cfg->discovery_url = (add_cfg->discovery_url ?
+ add_cfg->discovery_url :
+ base_cfg->discovery_url);
+
apr_thread_mutex_create(&new_cfg->server_mutex,
APR_THREAD_MUTEX_DEFAULT, p);
new_cfg->server = NULL;