diff options
Diffstat (limited to 'module')
-rw-r--r-- | module/mod_auth_singleid.c | 82 |
1 files changed, 77 insertions, 5 deletions
diff --git a/module/mod_auth_singleid.c b/module/mod_auth_singleid.c index 13770fd..4abd21f 100644 --- a/module/mod_auth_singleid.c +++ b/module/mod_auth_singleid.c @@ -108,6 +108,8 @@ typedef struct sid_context { sid_storage_t *store; sid_attribute_t *attributes; int redirect_after; + const char *logout_path; + const char *logout_dest; } sid_context_t; #define SID_AUTHTYPE "SingleID" @@ -187,6 +189,29 @@ get_token (apr_pool_t *pool, const char **line, const char *delims) return result; } +const int +compare_paths (const char *path1, const char *path2) +{ + size_t len1, len2; + if (!path1 && !path2) + return 0; + if (!path1) + return -1; + if (!path2) + return 1; + len1 = strlen(path1); + while (len1 && path1[len1 - 1] == '/') + --len1; + len2 = strlen(path2); + while (len2 && path2[len2 - 1] == '/') + --len2; + if (len1 < len2) + return -1; + if (len1 > len2) + return 1; + return strncmp (path1, path2, len1); +} + /* ------------------------------------------------------------------------------- * SHARED MEMORY and LOCKING */ @@ -523,6 +548,23 @@ set_redirect (cmd_parms *cmd, void *config, int val) return NULL; } +static const char* +set_logout (cmd_parms *cmd, void *config, const char *val1, const char *val2) +{ + sid_context_t *ctx = config; + + if (!val1 || val1[0] != '/') + return "The logout path must be an absolute path, and start with '/'"; + ctx->logout_path = apr_pstrdup (cmd->pool, val1); + + if (val2) + ctx->logout_dest = apr_pstrdup (cmd->pool, val2); + else + ctx->logout_dest = NULL; + + return NULL; +} + static const command_rec command_table[] = { AP_INIT_TAKE1 ("SingleIdProvider", set_identifier, NULL, OR_AUTHCFG, "The OpenID identifier we should perform identifier selection on when authenticating" ), @@ -538,6 +580,8 @@ static const command_rec command_table[] = { "Specify an attribute exchange url and alias."), AP_INIT_FLAG ("SingleIdRedirect", set_redirect, NULL, OR_AUTHCFG, "Redirect after authentication for a clean bookmarkable URL."), + AP_INIT_TAKE12 ("SingleIdLogout", set_logout, NULL, OR_AUTHCFG, + "Path at which to logout, and an optional second URL to redirect to after local logout."), { NULL } }; @@ -724,6 +768,22 @@ session_send_info (sid_context_t *ctx, request_rec *r, sid_session_t *sess) apr_table_addn (r->err_headers_out, "Set-Cookie", cookie); } +static void +session_send_clear (sid_context_t *ctx, request_rec *r) +{ + char *cookie; + + /* Build up a cookie which expires, to delete the cookie */ + cookie = apr_psprintf (r->pool, "%s=0; max-age=0; expires=Thu, 01-Jan-1970 00:00:01 GMT; httponly%s%s%s%s%s", + ctx->cookie_name, + ctx->cookie_domain ? "; domain=" : "", + ctx->cookie_domain ? ctx->cookie_domain : "", + ctx->cookie_path ? "; path=" : "", + ctx->cookie_path ? ctx->cookie_path : "", + ctx->cookie_secure ? "; secure" : ""); + apr_table_addn (r->err_headers_out, "Set-Cookie", cookie); +} + static sid_session_t* session_copy_info (apr_pool_t *p, sid_session_t *sess) { @@ -1113,6 +1173,23 @@ hook_authenticate (request_rec* r) if (ctx->identifier == NULL) return DECLINED; + req.result = OK; + req.rec = r; + req.sess = NULL; + req.output = NULL; + + /* Should we logout? */ + if (compare_paths (ctx->logout_path, r->uri) == 0) { + session_send_clear (ctx, r); + if (ctx->logout_dest) { + sid_request_respond_headers (&req, 302, "Found", + "Location", ctx->logout_dest, + "Cache-Control", "no-cache", + NULL); + } + return req.result; + } + mainreq = r; while (mainreq->main != NULL) @@ -1121,11 +1198,6 @@ hook_authenticate (request_rec* r) while (mainreq->prev != NULL) mainreq = mainreq->prev; - req.result = OK; - req.rec = r; - req.sess = NULL; - req.output = NULL; - /* Check if we've already authenticated this request */ sess = ap_get_module_config (mainreq->request_config, &auth_singleid_module); if (sess != NULL) { |