1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
From cdd25260d71faa1e54610a0bb4fada7809762fe3 Mon Sep 17 00:00:00 2001
From: "Studer Simon, I253 extern" <simon.studer@post.ch>
Date: Mon, 17 Aug 2020 14:34:35 +0200
Subject: [PATCH 1/2] Add config directive for SameSite cookie flag.
---
README | 5 +++++
src/mod_auth_cas.c | 30 +++++++++++++++++++++++-------
src/mod_auth_cas.h | 6 ++++--
3 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/README b/README
index c5c2e07..80385e9 100644
--- a/README
+++ b/README
@@ -275,6 +275,11 @@ Directive: CASCookieDomain
Default: NULL
Description: Specify the value for the 'Domain=' parameter in the Set-Cookie header.
+Directive: CASCookieSameSite
+Default: NULL
+Description: Specify the value for the 'SameSite=' parameter in the Set-Cookie header.
+ Allowed values are 'None', 'Lax', and 'Strict'.
+
Directive: CASCookieHttpOnly
Default: On
Description: Set the optional 'HttpOnly' flag for cookies issues by mod_auth_cas.
diff --git a/src/mod_auth_cas.c b/src/mod_auth_cas.c
index 327ca48..e34da59 100644
--- a/src/mod_auth_cas.c
+++ b/src/mod_auth_cas.c
@@ -115,6 +115,7 @@ void *cas_create_server_config(apr_pool_t *pool, server_rec *svr)
c->CASIdleTimeout = CAS_DEFAULT_COOKIE_IDLE_TIMEOUT;
c->CASCacheCleanInterval = CAS_DEFAULT_CACHE_CLEAN_INTERVAL;
c->CASCookieDomain = CAS_DEFAULT_COOKIE_DOMAIN;
+ c->CASCookieSameSite = CAS_DEFAULT_COOKIE_SAMESITE;
c->CASGatewayCookieDomain = CAS_DEFAULT_GATEWAY_COOKIE_DOMAIN;
c->CASCookieHttpOnly = CAS_DEFAULT_COOKIE_HTTPONLY;
c->CASSSOEnabled = CAS_DEFAULT_SSO_ENABLED;
@@ -152,6 +153,7 @@ void *cas_merge_server_config(apr_pool_t *pool, void *BASE, void *ADD)
c->CASIdleTimeout = (add->CASIdleTimeout != CAS_DEFAULT_COOKIE_IDLE_TIMEOUT ? add->CASIdleTimeout : base->CASIdleTimeout);
c->CASCacheCleanInterval = (add->CASCacheCleanInterval != CAS_DEFAULT_CACHE_CLEAN_INTERVAL ? add->CASCacheCleanInterval : base->CASCacheCleanInterval);
c->CASCookieDomain = (add->CASCookieDomain != CAS_DEFAULT_COOKIE_DOMAIN ? add->CASCookieDomain : base->CASCookieDomain);
+ c->CASCookieSameSite = (add->CASCookieSameSite != CAS_DEFAULT_COOKIE_SAMESITE ? add->CASCookieSameSite : base->CASCookieSameSite);
c->CASGatewayCookieDomain = (add->CASGatewayCookieDomain != CAS_DEFAULT_GATEWAY_COOKIE_DOMAIN ? add->CASGatewayCookieDomain : base->CASGatewayCookieDomain);
c->CASCookieHttpOnly = (add->CASCookieHttpOnly != CAS_DEFAULT_COOKIE_HTTPONLY ? add->CASCookieHttpOnly : base->CASCookieHttpOnly);
c->CASSSOEnabled = (add->CASSSOEnabled != CAS_DEFAULT_SSO_ENABLED ? add->CASSSOEnabled : base->CASSSOEnabled);
@@ -370,6 +372,15 @@ const char *cfg_readCASParameter(cmd_parms *cmd, void *cfg, const char *value)
}
c->CASCookieDomain = apr_pstrdup(cmd->pool, value);
break;
+ case cmd_cookie_samesite:
+ if (!((apr_strnatcasecmp(value, "None") == 0)
+ || (apr_strnatcasecmp(value, "Lax") == 0)
+ || (apr_strnatcasecmp(value, "Strict") == 0)))
+ {
+ return(apr_psprintf(cmd->pool, "MOD_AUTH_CAS: Invalid argument to CASCookieSameSite - must be 'None', 'Lax', or 'Strict'"));
+ }
+ c->CASCookieSameSite = apr_pstrdup(cmd->pool, value);
+ break;
case cmd_gateway_cookie_domain:
limit = strlen(value);
for(sz = 0; sz < limit; sz++) {
@@ -781,9 +792,9 @@ char *getCASCookie(request_rec *r, char *cookieName)
return rv;
}
-void setCASCookie(request_rec *r, char *cookieName, char *cookieValue, apr_byte_t secure, apr_time_t expireTime, char *cookieDomain)
+void setCASCookie(request_rec *r, char *cookieName, char *cookieValue, apr_byte_t secure, apr_time_t expireTime, char *cookieDomain, char *cookieSameSite)
{
- char *headerString, *currentCookies, *pathPrefix = "", *expireTimeString = NULL, *errString, *domainString = "";
+ char *headerString, *currentCookies, *pathPrefix = "", *expireTimeString = NULL, *errString, *domainString = "", *sameSiteString = "";
cas_cfg *c = ap_get_module_config(r->server->module_config, &auth_cas_module);
apr_status_t retVal;
@@ -805,13 +816,17 @@ void setCASCookie(request_rec *r, char *cookieName, char *cookieValue, apr_byte_
if(NULL != cookieDomain) {
domainString = apr_psprintf(r->pool, ";Domain=%s", cookieDomain);
}
- headerString = apr_psprintf(r->pool, "%s=%s%s;Path=%s%s%s%s%s",
+ if(NULL != cookieSameSite) {
+ sameSiteString = apr_psprintf(r->pool, ";SameSite=%s", cookieSameSite);
+ }
+ headerString = apr_psprintf(r->pool, "%s=%s%s;Path=%s%s%s%s%s%s",
cookieName,
cookieValue,
(secure ? ";Secure" : ""),
pathPrefix,
urlEncode(r, getCASScope(r), " "),
(cookieDomain != NULL ? domainString : ""),
+ (cookieSameSite != NULL ? sameSiteString : ""),
(c->CASCookieHttpOnly != FALSE ? "; HttpOnly" : ""),
(NULL == expireTimeString) ? "" : apr_psprintf(r->pool, "; expires=%s", expireTimeString));
@@ -2183,7 +2198,7 @@ int cas_authenticate(request_rec *r)
if(cookieString == NULL) { /* they have not made a gateway trip yet */
if(c->CASDebug)
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Gateway initial access (%s)", r->parsed_uri.path);
- setCASCookie(r, d->CASGatewayCookie, "TRUE", ssl, CAS_SESSION_EXPIRE_SESSION_SCOPE_TIMEOUT, c->CASGatewayCookieDomain);
+ setCASCookie(r, d->CASGatewayCookie, "TRUE", ssl, CAS_SESSION_EXPIRE_SESSION_SCOPE_TIMEOUT, c->CASGatewayCookieDomain, c->CASCookieSameSite);
redirectRequest(r, c);
return HTTP_MOVED_TEMPORARILY;
} else {
@@ -2208,10 +2223,10 @@ int cas_authenticate(request_rec *r)
if(cookieString == NULL)
return HTTP_INTERNAL_SERVER_ERROR;
- setCASCookie(r, (ssl ? d->CASSecureCookie : d->CASCookie), cookieString, ssl, CAS_SESSION_EXPIRE_SESSION_SCOPE_TIMEOUT, c->CASCookieDomain);
+ setCASCookie(r, (ssl ? d->CASSecureCookie : d->CASCookie), cookieString, ssl, CAS_SESSION_EXPIRE_SESSION_SCOPE_TIMEOUT, c->CASCookieDomain, c->CASCookieSameSite);
/* remove gateway cookie so they can reauthenticate later */
if (getCASCookie(r, d->CASGatewayCookie)) {
- setCASCookie(r, d->CASGatewayCookie, "TRUE", ssl, CAS_SESSION_EXPIRE_COOKIE_NOW, c->CASGatewayCookieDomain);
+ setCASCookie(r, d->CASGatewayCookie, "TRUE", ssl, CAS_SESSION_EXPIRE_COOKIE_NOW, c->CASGatewayCookieDomain, c->CASCookieSameSite);
}
r->user = remoteUser;
if(d->CASAuthNHeader != NULL)
@@ -2288,7 +2303,7 @@ int cas_authenticate(request_rec *r)
} else {
/* maybe the cookie expired, have the user get a new service ticket */
redirectRequest(r, c);
- setCASCookie(r, (ssl ? d->CASSecureCookie : d->CASCookie), "", ssl, CAS_SESSION_EXPIRE_COOKIE_NOW, c->CASCookieDomain);
+ setCASCookie(r, (ssl ? d->CASSecureCookie : d->CASCookie), "", ssl, CAS_SESSION_EXPIRE_COOKIE_NOW, c->CASCookieDomain, c->CASCookieSameSite);
return HTTP_MOVED_TEMPORARILY;
}
}
@@ -2895,6 +2910,7 @@ const command_rec cas_cmds [] = {
AP_INIT_TAKE1("CASCookiePath", cfg_readCASParameter, (void *) cmd_cookie_path, RSRC_CONF, "Path to store the CAS session cookies in (must end in trailing /)"),
AP_INIT_TAKE1("CASCookieEntropy", cfg_readCASParameter, (void *) cmd_cookie_entropy, RSRC_CONF, "Number of random bytes to use when generating a session cookie (larger values may result in slow cookie generation)"),
AP_INIT_TAKE1("CASCookieDomain", cfg_readCASParameter, (void *) cmd_cookie_domain, RSRC_CONF, "Specify domain header for mod_auth_cas cookie"),
+ AP_INIT_TAKE1("CASCookieSameSite", cfg_readCASParameter, (void *) cmd_cookie_samesite, RSRC_CONF, "Specify SameSite flag header for mod_auth_cas cookie"),
AP_INIT_TAKE1("CASGatewayCookieDomain", cfg_readCASParameter, (void *) cmd_gateway_cookie_domain, RSRC_CONF, "Specify domain header for mod_auth_cas gateway cookie"),
AP_INIT_TAKE1("CASCookieHttpOnly", cfg_readCASParameter, (void *) cmd_cookie_httponly, RSRC_CONF, "Enable 'HttpOnly' flag for mod_auth_cas cookie (may break RFC compliance)"),
AP_INIT_TAKE1("CASCookie", ap_set_string_slot, (void *) APR_OFFSETOF(cas_dir_cfg, CASCookie), ACCESS_CONF|OR_AUTHCFG, "Define the cookie name for HTTP sessions"),
diff --git a/src/mod_auth_cas.h b/src/mod_auth_cas.h
index 7650aa3..703c8a3 100644
--- a/src/mod_auth_cas.h
+++ b/src/mod_auth_cas.h
@@ -90,6 +90,7 @@
#define CAS_DEFAULT_ROOT_PROXIED_AS_URL NULL
#define CAS_DEFAULT_COOKIE_ENTROPY 32
#define CAS_DEFAULT_COOKIE_DOMAIN NULL
+#define CAS_DEFAULT_COOKIE_SAMESITE NULL
#define CAS_DEFAULT_COOKIE_HTTPONLY 1
#define CAS_DEFAULT_COOKIE_TIMEOUT 7200 /* 2 hours */
#define CAS_DEFAULT_COOKIE_IDLE_TIMEOUT 3600 /* 1 hour */
@@ -134,6 +135,7 @@ typedef struct cas_cfg {
char *CASCertificatePath;
char *CASCookiePath;
char *CASCookieDomain;
+ char *CASCookieSameSite;
char *CASGatewayCookieDomain;
char *CASAttributeDelimiter;
char *CASAttributePrefix;
@@ -175,7 +177,7 @@ typedef struct cas_curl_buffer {
typedef enum {
cmd_version, cmd_debug, cmd_validate_depth, cmd_ca_path, cmd_cookie_path,
cmd_loginurl, cmd_validateurl, cmd_proxyurl, cmd_cookie_entropy, cmd_session_timeout,
- cmd_idle_timeout, cmd_cache_interval, cmd_cookie_domain, cmd_cookie_httponly,
+ cmd_idle_timeout, cmd_cache_interval, cmd_cookie_domain, cmd_cookie_samesite, cmd_cookie_httponly,
cmd_sso, cmd_validate_saml, cmd_attribute_delimiter, cmd_attribute_prefix,
cmd_root_proxied_as, cmd_authoritative, cmd_preserve_ticket, cmd_gateway_cookie_domain
} valid_cmds;
@@ -208,7 +210,7 @@ char *getCASPath(request_rec *r);
void CASSAMLLogout(request_rec *r, char *body);
apr_status_t cas_in_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes);
void deleteCASCacheFile(request_rec *r, char *cookieName);
-void setCASCookie(request_rec *r, char *cookieName, char *cookieValue, apr_byte_t secure, apr_time_t expireTime, char *cookieDomain);
+void setCASCookie(request_rec *r, char *cookieName, char *cookieValue, apr_byte_t secure, apr_time_t expireTime, char *cookieDomain, char *cookieSameSite);
char *escapeString(const request_rec *r, const char *str);
char *urlEncode(const request_rec *r, const char *str, const char *charsToEncode);
char *getCASGateway(request_rec *r);
--
2.39.5
|