Honour MellonProbeDiscoveryIdP order when sending probes
git-svn-id: https://modmellon.googlecode.com/svn/trunk/mod_mellon2@139 a716ebb1-153a-0410-b759-cfb97c6a1b53
This commit is contained in:
parent
c7ebc20d0a
commit
08c4663f33
4
NEWS
4
NEWS
|
@ -1,3 +1,7 @@
|
|||
Version 0.4.1
|
||||
|
||||
* Honour MellonProbeDiscoveryIdP order when sending probes
|
||||
|
||||
Version 0.4.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ typedef struct am_dir_cfg_rec {
|
|||
/* IdP discovery service */
|
||||
const char *discovery_url;
|
||||
int probe_discovery_timeout;
|
||||
apr_hash_t *probe_discovery_idp;
|
||||
apr_table_t *probe_discovery_idp;
|
||||
|
||||
/* The configuration record we "inherit" the lasso server object from. */
|
||||
struct am_dir_cfg_rec *inherit_server_from;
|
||||
|
|
|
@ -77,6 +77,7 @@ static const apr_size_t post_size = 1024 * 1024 * 1024;
|
|||
*/
|
||||
static const int post_count = 100;
|
||||
|
||||
#if unused
|
||||
/* This function handles configuration directives which set a
|
||||
* multivalued string slot in the module configuration (the destination
|
||||
* strucure is a hash).
|
||||
|
@ -86,7 +87,6 @@ static const int post_count = 100;
|
|||
* directive.
|
||||
* void *struct_ptr Pointer to the current directory configuration.
|
||||
* NULL if we are not in a directory configuration.
|
||||
* This value isn't used by this function.
|
||||
* const char *key The string argument following this configuration
|
||||
* directive in the configuraion file.
|
||||
* const char *value Optional value to be stored in the hash.
|
||||
|
@ -117,6 +117,47 @@ static const char *am_set_hash_string_slot(cmd_parms *cmd,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* unused */
|
||||
|
||||
/* This function handles configuration directives which set a
|
||||
* multivalued string slot in the module configuration (the destination
|
||||
* strucure is a table).
|
||||
*
|
||||
* 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 *key The string argument following this configuration
|
||||
* directive in the configuraion file.
|
||||
* const char *value Optional value to be stored in the hash.
|
||||
*
|
||||
* Returns:
|
||||
* NULL on success or an error string on failure.
|
||||
*/
|
||||
static const char *am_set_table_string_slot(cmd_parms *cmd,
|
||||
void *struct_ptr,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
server_rec *s = cmd->server;
|
||||
apr_pool_t *pconf = s->process->pconf;
|
||||
am_dir_cfg_rec *cfg = (am_dir_cfg_rec *)struct_ptr;
|
||||
int offset;
|
||||
apr_table_t **table;
|
||||
|
||||
/*
|
||||
* If no value is given, we just store the key in the hash.
|
||||
*/
|
||||
if (value == NULL || *value == '\0')
|
||||
value = key;
|
||||
|
||||
offset = (int)(long)cmd->info;
|
||||
table = (apr_table_t **)((char *)cfg + offset);
|
||||
apr_table_set(*table, apr_pstrdup(pconf, key), value);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function handles configuration directives which set a file
|
||||
* slot in the module configuration. If lasso is recent enough, it
|
||||
|
@ -1009,7 +1050,7 @@ const command_rec auth_mellon_commands[] = {
|
|||
),
|
||||
AP_INIT_TAKE12(
|
||||
"MellonProbeDiscoveryIdP",
|
||||
am_set_hash_string_slot,
|
||||
am_set_table_string_slot,
|
||||
(void *)APR_OFFSETOF(am_dir_cfg_rec, probe_discovery_idp),
|
||||
OR_AUTHCFG,
|
||||
"An IdP that can be used for IdP probe discovery."
|
||||
|
@ -1098,7 +1139,7 @@ void *auth_mellon_dir_config(apr_pool_t *p, char *d)
|
|||
dir->login_path = default_login_path;
|
||||
dir->discovery_url = NULL;
|
||||
dir->probe_discovery_timeout = -1; /* -1 means no probe discovery */
|
||||
dir->probe_discovery_idp = apr_hash_make(p);
|
||||
dir->probe_discovery_idp = apr_table_make(p, 0);
|
||||
|
||||
dir->sp_org_name = apr_hash_make(p);
|
||||
dir->sp_org_display_name = apr_hash_make(p);
|
||||
|
@ -1293,10 +1334,10 @@ void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add)
|
|||
add_cfg->probe_discovery_timeout :
|
||||
base_cfg->probe_discovery_timeout);
|
||||
|
||||
new_cfg->probe_discovery_idp = apr_hash_copy(p,
|
||||
(apr_hash_count(add_cfg->probe_discovery_idp) > 0) ?
|
||||
add_cfg->probe_discovery_idp :
|
||||
base_cfg->probe_discovery_idp);
|
||||
new_cfg->probe_discovery_idp = apr_table_copy(p,
|
||||
(!apr_is_empty_table(add_cfg->probe_discovery_idp)) ?
|
||||
add_cfg->probe_discovery_idp :
|
||||
base_cfg->probe_discovery_idp);
|
||||
|
||||
|
||||
if (cfg_can_inherit_lasso_server(add_cfg)) {
|
||||
|
|
|
@ -2577,6 +2577,38 @@ static int am_handle_login(request_rec *r)
|
|||
return am_send_authn_request(r, idp, return_to, is_passive);
|
||||
}
|
||||
|
||||
/* This function probes an URL (HTTP GET)
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request.
|
||||
* const char *url The URL
|
||||
* int timeout Timeout in seconds
|
||||
*
|
||||
* Returns:
|
||||
* OK on success, or an error if any of the steps fail.
|
||||
*/
|
||||
static int am_probe_url(request_rec *r, const char *url, int timeout)
|
||||
{
|
||||
void *dontcare;
|
||||
apr_size_t len;
|
||||
long status;
|
||||
int error;
|
||||
|
||||
status = 0;
|
||||
if ((error = am_httpclient_get(r, url, &dontcare, &len,
|
||||
timeout, &status)) != OK)
|
||||
return error;
|
||||
|
||||
if (status != HTTP_OK) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Probe on \"%s\" returned HTTP %ld",
|
||||
url, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* This function handles requests to the probe discovery handler
|
||||
*
|
||||
* Parameters:
|
||||
|
@ -2588,10 +2620,8 @@ static int am_handle_login(request_rec *r)
|
|||
static int am_handle_probe_discovery(request_rec *r) {
|
||||
am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
|
||||
LassoServer *server;
|
||||
const char *idp = NULL;
|
||||
const char *disco_idp = NULL;
|
||||
int timeout;
|
||||
GList *idp_list;
|
||||
GList *iter;
|
||||
char *return_to;
|
||||
char *idp_param;
|
||||
char *redirect_url;
|
||||
|
@ -2650,75 +2680,69 @@ static int am_handle_probe_discovery(request_rec *r) {
|
|||
/*
|
||||
* Proceed with built-in IdP discovery.
|
||||
*
|
||||
* Send probes for all configured IdP to check availability.
|
||||
* The first to answer is chosen, but the list of usable
|
||||
* IdP can be restricted in configuration.
|
||||
* First try sending probes to IdP configured for discovery.
|
||||
* Second send probes for all configured IdP
|
||||
* The first to answer is chosen.
|
||||
* If none answer, use the first configured IdP
|
||||
*/
|
||||
idp_list = g_hash_table_get_keys(server->providers);
|
||||
for (iter = idp_list; iter != NULL; iter = iter->next) {
|
||||
void *dontcare;
|
||||
const char *ping_url;
|
||||
apr_size_t len;
|
||||
long status;
|
||||
if (!apr_is_empty_table(cfg->probe_discovery_idp)) {
|
||||
const apr_array_header_t *header;
|
||||
apr_table_entry_t *elts;
|
||||
const char *url;
|
||||
const char *idp;
|
||||
int i;
|
||||
|
||||
idp = iter->data;
|
||||
ping_url = idp;
|
||||
header = apr_table_elts(cfg->probe_discovery_idp);
|
||||
elts = (apr_table_entry_t *)header->elts;
|
||||
|
||||
/*
|
||||
* If a list of IdP was given for probe discovery,
|
||||
* skip any IdP that does not match.
|
||||
*/
|
||||
if (apr_hash_count(cfg->probe_discovery_idp) != 0) {
|
||||
char *value = apr_hash_get(cfg->probe_discovery_idp,
|
||||
idp, APR_HASH_KEY_STRING);
|
||||
for (i = 0; i < header->nelts; i++) {
|
||||
idp = elts[i].key;
|
||||
url = elts[i].val;
|
||||
|
||||
if (value == NULL) {
|
||||
/* idp not in list, try the next one */
|
||||
continue;
|
||||
} else {
|
||||
/* idp in list, use the value as the ping url */
|
||||
ping_url = value;
|
||||
if (am_probe_url(r, url, timeout) == OK) {
|
||||
disco_idp = idp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GList *iter;
|
||||
GList *idp_list;
|
||||
const char *idp;
|
||||
|
||||
status = 0;
|
||||
if (am_httpclient_get(r, ping_url, &dontcare, &len,
|
||||
timeout, &status) != OK)
|
||||
continue;
|
||||
|
||||
if (status != HTTP_OK) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Cannot probe %s: \"%s\" returned HTTP %ld",
|
||||
idp, ping_url, status);
|
||||
continue;
|
||||
idp_list = g_hash_table_get_keys(server->providers);
|
||||
for (iter = idp_list; iter != NULL; iter = iter->next) {
|
||||
idp = iter->data;
|
||||
|
||||
if (am_probe_url(r, idp, timeout) == OK) {
|
||||
disco_idp = idp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We got some succes */
|
||||
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
|
||||
"probeDiscovery using %s", idp);
|
||||
break;
|
||||
g_list_free(idp_list);
|
||||
}
|
||||
g_list_free(idp_list);
|
||||
|
||||
/*
|
||||
* On failure, try default
|
||||
*/
|
||||
if (idp == NULL) {
|
||||
idp = am_first_idp(r);
|
||||
if (idp == NULL) {
|
||||
if (disco_idp == NULL) {
|
||||
disco_idp = am_first_idp(r);
|
||||
if (disco_idp == NULL) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"probeDiscovery found no usable IdP.");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
} else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "probeDiscovery "
|
||||
"failed, trying default IdP %s", idp);
|
||||
"failed, trying default IdP %s", disco_idp);
|
||||
}
|
||||
} else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
|
||||
"probeDiscovery using %s", disco_idp);
|
||||
}
|
||||
|
||||
redirect_url = apr_psprintf(r->pool, "%s%s%s=%s", return_to,
|
||||
strchr(return_to, '?') ? "&" : "?",
|
||||
am_urlencode(r->pool, idp_param),
|
||||
am_urlencode(r->pool, idp));
|
||||
am_urlencode(r->pool, disco_idp));
|
||||
|
||||
apr_table_setn(r->headers_out, "Location", redirect_url);
|
||||
|
||||
|
|
Loading…
Reference in New Issue