Commit 2ff21e09 authored by godog's avatar godog

mod_sso: finish porting to apache2.4, TODO: groups support

parent 6a35f8a2
...@@ -37,6 +37,11 @@ ...@@ -37,6 +37,11 @@
#include "mod_sso.h" #include "mod_sso.h"
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
#define SSO_REQUIRE_NAME "sso"
#include "mod_auth.h"
#endif
extern module AP_MODULE_DECLARE_DATA sso_module; extern module AP_MODULE_DECLARE_DATA sso_module;
typedef struct { typedef struct {
...@@ -51,6 +56,10 @@ typedef struct { ...@@ -51,6 +56,10 @@ typedef struct {
apr_array_header_t *groups; apr_array_header_t *groups;
} modsso_config; } modsso_config;
typedef struct {
apr_array_header_t *user_groups;
} modsso_request_notes;
typedef const char *(*CMD_HAND_TYPE) (); typedef const char *(*CMD_HAND_TYPE) ();
/** /**
...@@ -418,9 +427,14 @@ static int mod_sso_method_handler(request_rec *r) ...@@ -418,9 +427,14 @@ static int mod_sso_method_handler(request_rec *r)
ap_get_module_config(r->per_dir_config, &sso_module); ap_get_module_config(r->per_dir_config, &sso_module);
uri = r->uri; uri = r->uri;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"sso: handler \"%s\"", r->handler);
// Return immediately if there's nothing to do (check the AuthType) // Return immediately if there's nothing to do (check the AuthType)
type = ap_auth_type(r); type = ap_auth_type(r);
if (!type || strcasecmp(type, "SSO") != 0) { if (!type || strcasecmp(type, "SSO") != 0) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"sso: invalid authentication type \"%s\"", type);
return DECLINED; return DECLINED;
} }
...@@ -487,6 +501,7 @@ struct modsso_auth_req { ...@@ -487,6 +501,7 @@ struct modsso_auth_req {
int any_user; int any_user;
}; };
#if MODULE_MAGIC_NUMBER_MAJOR < 20100714
static int array_contains(apr_array_header_t *arr, const char *s) static int array_contains(apr_array_header_t *arr, const char *s)
{ {
int i; int i;
...@@ -564,6 +579,7 @@ static void mod_sso_parse_requirements(request_rec *r, ...@@ -564,6 +579,7 @@ static void mod_sso_parse_requirements(request_rec *r,
*(const char **)apr_array_push(auth->groups) = NULL; *(const char **)apr_array_push(auth->groups) = NULL;
} }
} }
#endif
static char *encode_groups(apr_pool_t *p, apr_array_header_t *groups) static char *encode_groups(apr_pool_t *p, apr_array_header_t *groups)
{ {
...@@ -632,16 +648,19 @@ static int mod_sso_check_user_id(request_rec *r) ...@@ -632,16 +648,19 @@ static int mod_sso_check_user_id(request_rec *r)
const char *sso_login_path, *sso_logout_path; const char *sso_login_path, *sso_logout_path;
const char *service = NULL, *service_host = NULL, const char *service = NULL, *service_host = NULL,
*service_path = NULL; *service_path = NULL;
struct modsso_auth_req auth;
int retval, err, do_redirect = 1; int retval, err, do_redirect = 1;
modsso_config *s_cfg = (modsso_config *) modsso_config *s_cfg = (modsso_config *)
ap_get_module_config(r->per_dir_config, &sso_module); ap_get_module_config(r->per_dir_config, &sso_module);
apr_array_header_t *sso_validate_groups = NULL;
type = ap_auth_type(r); type = ap_auth_type(r);
if (type == NULL || apr_strnatcasecmp(type, "sso") != 0) { if (type == NULL || apr_strnatcasecmp(type, "sso") != 0) {
return DECLINED; return DECLINED;
} }
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"sso (check_user_id): handler '%s'", r->handler);
// If this is a sub-request, pass existing credentials, if any. // If this is a sub-request, pass existing credentials, if any.
if (!ap_is_initial_req(r)) { if (!ap_is_initial_req(r)) {
if (r->main != NULL) { if (r->main != NULL) {
...@@ -677,8 +696,6 @@ static int mod_sso_check_user_id(request_rec *r) ...@@ -677,8 +696,6 @@ static int mod_sso_check_user_id(request_rec *r)
return OK; return OK;
} }
//mod_sso_parse_requirements(r, &auth);
// Test for valid cookie // Test for valid cookie
sso_cookie = get_cookie(r, sso_cookie_name); sso_cookie = get_cookie(r, sso_cookie_name);
if (sso_cookie != NULL) { if (sso_cookie != NULL) {
...@@ -702,31 +719,28 @@ static int mod_sso_check_user_id(request_rec *r) ...@@ -702,31 +719,28 @@ static int mod_sso_check_user_id(request_rec *r)
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,
"sso: ticket decoding error: %s", sso_strerror(err)); "sso: ticket decoding error: %s", sso_strerror(err));
} else { } else {
err = sso_validate(t, s_cfg->service, s_cfg->domain, apr_is_empty_array(auth.groups) ? NULL : (const char **)auth.groups->elts); if (s_cfg->groups != NULL) {
sso_validate_groups = apr_array_copy(r->pool, s_cfg->groups);
*(const char **)apr_array_push(sso_validate_groups) = NULL;
}
err = sso_validate(t, s_cfg->service, s_cfg->domain,
apr_is_empty_array(s_cfg->groups) ? NULL : (const char **)sso_validate_groups);
if (err != SSO_OK) { if (err != SSO_OK) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,
"sso: validation error: %s", sso_strerror(err)); "sso: validation error: %s", sso_strerror(err));
} else { } else {
// Check user authorization lists. Group membership has
// already been verified by sso_validate.
if (auth.any_user || (!apr_is_empty_array(auth.users) && array_contains(auth.users, t->user)) || !apr_is_empty_array(auth.groups)) {
// Success.
apr_table_setn(r->subprocess_env, "SSO_SERVICE", apr_table_setn(r->subprocess_env, "SSO_SERVICE",
apr_pstrdup(r->pool, service)); apr_pstrdup(r->pool, service));
r->user = apr_pstrdup(r->pool, t->user); r->user = apr_pstrdup(r->pool, t->user);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"sso: authorized user '%s'", r->user); "sso: authorized user '%s'",
r->user);
retval = OK; retval = OK;
} else {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,
"sso: unauthorized user '%s'", t->user);
retval = HTTP_UNAUTHORIZED;
}
do_redirect = 0; do_redirect = 0;
} }
sso_ticket_free(t);
} }
sso_ticket_free(t);
} }
if (!do_redirect) { if (!do_redirect) {
...@@ -734,7 +748,7 @@ static int mod_sso_check_user_id(request_rec *r) ...@@ -734,7 +748,7 @@ static int mod_sso_check_user_id(request_rec *r)
} }
// Redirect to login server // Redirect to login server
return redirect_to_login_server(r, s_cfg->login_server, service_host, service, auth.groups); return redirect_to_login_server(r, s_cfg->login_server, service_host, service, s_cfg->groups);
} }
#else #else
static int mod_sso_check_user_id(request_rec *r) static int mod_sso_check_user_id(request_rec *r)
...@@ -853,10 +867,39 @@ static int mod_sso_check_user_id(request_rec *r) ...@@ -853,10 +867,39 @@ static int mod_sso_check_user_id(request_rec *r)
* Apache authorization check callback for mod_sso. * Apache authorization check callback for mod_sso.
*/ */
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
static authz_status mod_sso_auth_checker(request_rec *r, const char *require_args, const void *parsed_require_args) static authz_status sso_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
{ {
const char *uri, *type;
const char *service = NULL, *service_host = NULL,
*service_path = NULL;
char *sso_logout_path, *sso_login_path;
modsso_config *s_cfg;
// We already did everything in mod_sso_check_user_id(),
// so just succeed (if SSO is active).
type = ap_auth_type(r);
if (type && !strcasecmp(type, "SSO") && r->user) {
return OK;
}
// XXX check groups via e.g. 'Require sso-groups' or 'Require valid-group'
s_cfg = (modsso_config *)
ap_get_module_config(r->per_dir_config, &sso_module);
uri = r->uri;
if (parse_service(r, s_cfg, &service, &service_host, &service_path) != 0) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"sso (auth_checker): could not parse service \"%s\"",
s_cfg->service);
return HTTP_BAD_REQUEST;
}
sso_logout_path = apr_pstrcat(r->pool, service_path, "sso_logout", NULL);
sso_login_path = apr_pstrcat(r->pool, service_path, "sso_login", NULL);
if (!strcmp(uri, sso_logout_path) || !strcmp(uri, sso_login_path)) {
return OK;
}
return DECLINED;
} }
#else #else
static int mod_sso_auth_checker(request_rec *r) static int mod_sso_auth_checker(request_rec *r)
...@@ -894,6 +937,13 @@ static int mod_sso_auth_checker(request_rec *r) ...@@ -894,6 +937,13 @@ static int mod_sso_auth_checker(request_rec *r)
} }
#endif #endif
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
static const authz_provider authz_sso_provider =
{
&sso_check_authorization,
NULL,
};
#endif
/** /**
* Apache register_hooks callback for mod_sso. * Apache register_hooks callback for mod_sso.
...@@ -908,7 +958,7 @@ static void mod_sso_register_hooks (apr_pool_t *p) ...@@ -908,7 +958,7 @@ static void mod_sso_register_hooks (apr_pool_t *p)
ap_hook_handler(mod_sso_method_handler, NULL, NULL, APR_HOOK_FIRST); ap_hook_handler(mod_sso_method_handler, NULL, NULL, APR_HOOK_FIRST);
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
ap_hook_check_authn(mod_sso_check_user_id, NULL, NULL, APR_HOOK_MIDDLE, AP_AUTH_INTERNAL_PER_CONF); ap_hook_check_authn(mod_sso_check_user_id, NULL, NULL, APR_HOOK_MIDDLE, AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(pool, AUTHZ_PROVIDER_GROUP, SSO_REQUIRE_NAME, "0", &authz_sso_provider, AP_AUTH_INTERNAL_PER_CONF); ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, SSO_REQUIRE_NAME, "0", &authz_sso_provider, AP_AUTH_INTERNAL_PER_CONF);
#else #else
static const char * const authzSucc[] = { "mod_sso.c", NULL }; static const char * const authzSucc[] = { "mod_sso.c", NULL };
ap_hook_check_user_id(mod_sso_check_user_id, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_check_user_id(mod_sso_check_user_id, NULL, NULL, APR_HOOK_MIDDLE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment