summaryrefslogtreecommitdiff
path: root/module/mod_auth_singleid.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2010-02-11 16:10:05 +0000
committerStef Walter <stef@memberwebs.com>2010-02-11 16:10:05 +0000
commit3f923ddf153e4d940731ba94ffba251d47f9071d (patch)
treea03c7ca3c78fdd6887615f4c0ef8a5f3bdf9f2a3 /module/mod_auth_singleid.c
parent3969967cfc767daf6e5f52b58e8dd7305443160d (diff)
Add support for logout path and redirect after logout.
Diffstat (limited to 'module/mod_auth_singleid.c')
-rw-r--r--module/mod_auth_singleid.c82
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) {