Hello community,
here is the log from the commit of package apache2-mod_auth_mellon for
openSUSE:Factory checked in at 2020-09-10 22:53:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/apache2-mod_auth_mellon (Old)
and /work/SRC/openSUSE:Factory/.apache2-mod_auth_mellon.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apache2-mod_auth_mellon"
Thu Sep 10 22:53:50 2020 rev:3 rq:833494 version:0.17.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/apache2-mod_auth_mellon/apache2-mod_auth_mellon.changes
2020-06-04 17:56:30.809016223 +0200
+++
/work/SRC/openSUSE:Factory/.apache2-mod_auth_mellon.new.4249/apache2-mod_auth_mellon.changes
2020-09-10 22:55:26.884430178 +0200
@@ -1,0 +2,20 @@
+Thu Sep 10 14:19:03 UTC 2020 - Kristyna Streitova <[email protected]>
+
+- Update to 0.17.0
+ * New option MellonSendExpectHeader (default On) which allows to
+ disable sending the Expect header in the HTTP-Artifact binding to
+ improve performance when the remote party does not support this
+ header.
+ * Set SameSite attribute to None on on the cookietest cookie.
+ * Bump default generated keysize to 3072 bits in
+ mellon_create_metadata
+ * Validate if the assertion ID has not been used earlier before
+ creating a new session.
+ * Release session cache after calling invalidate endpoint.
+ * In MellonCond directives, fix a bug that setting the NC option
+ would also activate substring match and that REG would activate
+ REF.
+ * Fix MellonCond substring match to actually match the substring on
+ the attribute value
+
+-------------------------------------------------------------------
Old:
----
mod_auth_mellon-0.16.0.tar.gz
New:
----
mod_auth_mellon-0.17.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ apache2-mod_auth_mellon.spec ++++++
--- /var/tmp/diff_new_pack.xh8PLW/_old 2020-09-10 22:55:27.428430975 +0200
+++ /var/tmp/diff_new_pack.xh8PLW/_new 2020-09-10 22:55:27.428430975 +0200
@@ -17,15 +17,14 @@
%define upstream_name mod_auth_mellon
-%define version_path 0_16_0
Name: apache2-mod_auth_mellon
-Version: 0.16.0
+Version: 0.17.0
Release: 0
Summary: A SAML 2.0 authentication module for the Apache Server
License: GPL-2.0-or-later
Group: Productivity/Networking/Web/Servers
URL: https://github.com/latchset/%{upstream_name}
-Source0:
https://github.com/latchset/%{upstream_name}/releases/download/v%{version_path}/%{upstream_name}-%{version}.tar.gz
+Source0:
https://github.com/latchset/%{upstream_name}/releases/download/v%{version}/%{upstream_name}-%{version}.tar.gz
Source1: %{upstream_name}.conf
Source2: %{name}.conf
Source3: README.diagnostics
++++++ mod_auth_mellon-0.16.0.tar.gz -> mod_auth_mellon-0.17.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/NEWS
new/mod_auth_mellon-0.17.0/NEWS
--- old/mod_auth_mellon-0.16.0/NEWS 2020-01-28 15:59:44.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/NEWS 2020-09-08 12:52:15.000000000 +0200
@@ -1,3 +1,29 @@
+Version 0.17.0
+---------------------------------------------------------------------------
+
+Enhancements:
+
+ * New option MellonSendExpectHeader (default On) which allows to disable
+ sending the Expect header in the HTTP-Artifact binding to improve
+ performance when the remote party does not support this header.
+
+ * Set SameSite attribute to None on on the cookietest cookie.
+
+ * Bump default generated keysize to 3072 bits in mellon_create_metadata.
+
+Bug fixes:
+
+ * Validate if the assertion ID has not been used earlier before creating
+ a new session.
+
+ * Release session cache after calling invalidate endpoint.
+
+ * In MellonCond directives, fix a bug that setting the NC option would
+ also activate substring match and that REG would activate REF.
+
+ * Fix MellonCond substring match to actually match the substring on
+ the attribute value.
+
Version 0.16.0
---------------------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/README.md
new/mod_auth_mellon-0.17.0/README.md
--- old/mod_auth_mellon-0.16.0/README.md 2020-01-28 15:59:44.000000000
+0100
+++ new/mod_auth_mellon-0.17.0/README.md 2020-09-08 12:52:15.000000000
+0200
@@ -222,21 +222,32 @@
# When using none, you should set "MellonSecureCookie On" to prevent
# compatibility issues with newer browsers.
# If not set, the SameSite attribute is not set on the cookie. In newer
- # browsers, this may cause SameSite to default to "Lax"
+ # browsers, this may cause SameSite to default to "Lax".
+ # Note: Regardless of the value set here a fixed SameSite value of
+ # None is used for the cookie test. The cookie test, which is performed
+ # with a static value, should detect whether the user's client accepts
+ # cookies or not before the auth_mellon session is established and thus
+ # avoid a redirect loop. Using a fixed SameSite value of None ensures
+ # that the cookie with the static value does not get lost in the
+ # HTTP-POST binding request issued by the autosubmit form returned by
+ # the IDP.
# Default: not set
# MellonCookieSameSite lax
# Some browsers will reject cookies if SameSite is specified.
- # MELLON_DISABLE_SAMESITE environment variable suppresses
- # unnecessary setting of SameSite cookies
- # SetEnvIf User-Agent ^.*Chrome\/(5[1-9]|6[0-6]).*$
MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*Android.*UCBrowser\/([0-9]|1[0-1]).*$
MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*Android.*UCBrowser\/12\.([0-9]|1[0-2]).*$
MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*Android.*UCBrowser\/12\.13\.[0-1].*$
MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*iPhone; CPU iPhone OS 1[0-2].*$
MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*iPad; CPU OS 1[0-2].*$ MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*iPod touch; CPU iPhone OS 1[0-2].*$
MELLON_DISABLE_SAMESITE
- # SetEnvIf User-Agent ^.*Macintosh; Intel Mac OS
X.*Version\/1[0-2].*Safari.*$ MELLON_DISABLE_SAMESITE
+ # The MELLON_DISABLE_SAMESITE environment variable suppresses
+ # setting of SameSite cookies. You can use the following directives
+ # to set it.
+ # BrowserMatch "\(iP.+; CPU .*OS 12[_\d]*.*\) AppleWebKit\/"
MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "\(Macintosh; Intel Mac OS X 10_14_\d\)
AppleWebKit\/[\.\d]+ \(KHTML, like Gecko\)$" MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "Outlook-iOS" MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "UCBrowser\/(8|9|10|11)\.(\d+)\.(\d+)[\.\d]* "
MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "UCBrowser\/12\.13\.[0-1][\.\d]* "
MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "UCBrowser\/12\.1[0-2]\.(\d+)[\.\d]* "
MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "UCBrowser\/12\.\d\.(\d+)[\.\d]* "
MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "Chrom[^ \/]+\/6[0-6][\.\d]* " MELLON_DISABLE_SAMESITE=1
+ # BrowserMatch "Chrom[^ \/]+\/5[1-9][\.\d]* " MELLON_DISABLE_SAMESITE=1
+
# MellonUser selects which attribute we should use for the username.
# The username is passed on to other apache modules and to the web
@@ -299,15 +310,6 @@
# Default: MellonEnvVarsSetCount Off
MellonEnvVarsSetCount On
- # If MellonSessionDump is set, then the SAML session will be
- # available in the MELLON_SESSION environment variable
- MellonSessionDump Off
-
- # If MellonSamlResponseDump is set, then the SAML authentication
- # response will be available in the MELLON_SAML_RESPONSE environment
- # variable
- MellonSamlResponseDump Off
-
# MellonRequire allows you to limit access to those with specific
# attributes. The syntax is
# 'MellonRequire <attribute name> <list of valid values>'.
@@ -765,14 +767,30 @@
invalidated and the session will be removed from the mod_auth_mellon cache.
SLO will not be possible after the mod_auth_mellon session is invalidated.
If this functionality is enabled, invalidate the session by calling
-the endpoint "<endpoint path>/invalidate".
-Here is a sample configuration to enabled this feature:
+the endpoint "<endpoint path>/invalidate?ReturnTo=<valid url>".
+The "ReturnTo" parameter is required.
+
+Here is a sample configuration to enable this feature:
```ApacheConf
MellonEnabledInvalidateSessionEndpoint On
```
Default value is Off
+## Send Expect Header
+The Expect Header saves an additional network round-trip and is thus a good
idea when
+the request isn't extremely large and the probability for rejection is low.
+For some Apache server versions, the Expect Header is not properly managed and
a curl command will
+wait for 1 second before sending the body of the request.
+If the Expect Header is not present, there won't be wait time in the
HTTP-Artifact binding.
+
+Here is a sample configuration to not send the Expect header:
+```ApacheConf
+MellonSendExpectHeader Off
+```
+Default value is On
+
+
## Probe IdP discovery
mod_auth_mellon has an IdP probe discovery service that sends HTTP GET
@@ -911,14 +929,6 @@
Editing, appending, and overwriting headers is possible in other cases.
-## Support
-
-There's a mailing list for discussion and support.
-
-* To subscribe: https://sympa.uninett.no/lists/uninett.no/subscribe/modmellon
-* List archives: https://sympa.uninett.no/lists/uninett.no/arc/modmellon
-
-
## Reporting security vulnerabilities
For reporting security vulnerabilities in mod_auth_mellon, please contact
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon.h
new/mod_auth_mellon-0.17.0/auth_mellon.h
--- old/mod_auth_mellon-0.16.0/auth_mellon.h 2020-01-28 15:59:44.000000000
+0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon.h 2020-09-08 12:52:15.000000000
+0200
@@ -100,6 +100,9 @@
/* Disable SameSite Environment Value */
#define AM_DISABLE_SAMESITE_ENV_VAR "MELLON_DISABLE_SAMESITE"
+/* Force setting SameSite to None */
+#define AM_FORCE_SAMESITE_NONE_NOTE "MELLON_FORCE_SAMESITE_NONE"
+
/* This is the length of the id we use (for session IDs and
* replaying POST data).
@@ -324,6 +327,10 @@
/* Enabled the session invalidate endpoint. */
int enabled_invalidation_session;
+
+ /* Send Expect Header. */
+ int send_expect_header;
+
} am_dir_cfg_rec;
/* Bitmask for PAOS service options */
@@ -379,7 +386,8 @@
typedef enum {
AM_CACHE_SESSION,
- AM_CACHE_NAMEID
+ AM_CACHE_NAMEID,
+ AM_CACHE_ASSERTIONID
} am_cache_key_t;
/* Type for configuring environment variable names */
@@ -482,6 +490,8 @@
am_cache_entry_t *am_get_request_session(request_rec *r);
am_cache_entry_t *am_get_request_session_by_nameid(request_rec *r,
char *nameid);
+am_cache_entry_t *am_get_request_session_by_assertionid(request_rec *r,
+ char *assertionid);
am_cache_entry_t *am_new_request_session(request_rec *r);
void am_release_request_session(request_rec *r, am_cache_entry_t *session);
void am_delete_request_session(request_rec *r, am_cache_entry_t *session);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_cache.c
new/mod_auth_mellon-0.17.0/auth_mellon_cache.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_cache.c 2020-01-14
14:01:03.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_cache.c 2020-09-08
12:52:15.000000000 +0200
@@ -1,7 +1,7 @@
/*
*
* auth_mellon_cache.c: an authentication apache module
- * Copyright � 2003-2007 UNINETT (http://www.uninett.no/)
+ * Copyright © 2003-2007 UNINETT (http://www.uninett.no/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -71,7 +71,7 @@
*
* Parameters:
* request_rec *r The request we are processing.
- * am_cache_key_t type AM_CACHE_SESSION or AM_CACHE_NAMEID
+ * am_cache_key_t type AM_CACHE_SESSION, AM_CACHE_NAMEID or
AM_CACHE_ASSERTIONID
* const char *key The session key or user
*
* Returns:
@@ -98,6 +98,7 @@
return NULL;
break;
case AM_CACHE_NAMEID:
+ case AM_CACHE_ASSERTIONID:
break;
default:
return NULL;
@@ -135,6 +136,10 @@
/* tablekey may be NULL */
tablekey = am_cache_env_fetch_first(e, "NAME_ID");
break;
+ case AM_CACHE_ASSERTIONID:
+ /* tablekey may be NULL */
+ tablekey = am_cache_env_fetch_first(e, "ASSERTION_ID");
+ break;
default:
tablekey = NULL;
break;
@@ -324,7 +329,7 @@
current_time = apr_time_now();
/* We will use 't' to remember the best/oldest entry. We
- * initalize it to the first entry in the table to simplify the
+ * initialize it to the first entry in the table to simplify the
* following code (saves test for t == NULL).
*/
t = am_cache_entry_ptr(mod_cfg, table, 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_config.c
new/mod_auth_mellon-0.17.0/auth_mellon_config.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_config.c 2020-01-14
14:02:57.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_config.c 2020-09-08
12:52:15.000000000 +0200
@@ -114,6 +114,10 @@
*/
static const int default_enabled_invalidation_session = 0;
+/* The default setting to send the Expect Header.
+ */
+static const int default_send_expect_header = 1;
+
/* This function handles configuration directives which set a
* multivalued string slot in the module configuration (the destination
* strucure is a hash).
@@ -824,7 +828,7 @@
};
apr_size_t options_count = sizeof(options) / sizeof(*options);
- /* Skip inital [ */
+ /* Skip initial [ */
if (arg[0] == '[')
arg++;
else
@@ -1275,6 +1279,37 @@
return NULL;
}
+/* This function handles the MellonSendExpectHeader configuration directive.
+ * This directive can be set to "on" (default) or "off".
+ *
+ * Parameters:
+ * cmd_parms *cmd The command structure for this configuration
+ * directive.
+ * void *struct_ptr Pointer to the current directory configuration.
+ * const char *arg The string argument following this configuration
+ * directive in the configuraion file.
+ *
+ * Returns:
+ * NULL on success or an error string if the argument is wrong.
+ */
+static const char *am_set_send_expect_header_slots(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg)
+{
+ am_dir_cfg_rec *d = (am_dir_cfg_rec *)struct_ptr;
+
+ if (strcasecmp(arg, "on") == 0) {
+ d->send_expect_header = 1;
+ }
+ else if (strcasecmp(arg, "off") == 0) {
+ d->send_expect_header = 0;
+ } else {
+ return apr_psprintf(cmd->pool, "%s: must be one of: 'on', 'off'",
+ cmd->cmd->name);
+ }
+
+ return NULL;
+}
/* This array contains all the configuration directive which are handled
* by auth_mellon.
@@ -1754,6 +1789,13 @@
OR_AUTHCFG,
"Enabled the session invalidation endpoint. Default is 'off'."
),
+ AP_INIT_TAKE1(
+ "MellonSendExpectHeader",
+ am_set_send_expect_header_slots,
+ NULL,
+ OR_AUTHCFG,
+ "Send the Expect Header. Default is 'on'."
+ ),
{NULL}
};
@@ -1863,6 +1905,8 @@
dir->enabled_invalidation_session = default_enabled_invalidation_session;
+ dir->send_expect_header = default_send_expect_header;
+
return dir;
}
@@ -2125,6 +2169,11 @@
add_cfg->enabled_invalidation_session :
base_cfg->enabled_invalidation_session);
+ new_cfg->send_expect_header =
+ (add_cfg->send_expect_header != default_send_expect_header ?
+ add_cfg->send_expect_header :
+ base_cfg->send_expect_header);
+
return new_cfg;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_cookie.c
new/mod_auth_mellon-0.17.0/auth_mellon_cookie.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_cookie.c 2020-01-28
15:59:44.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_cookie.c 2020-09-08
12:52:15.000000000 +0200
@@ -78,7 +78,11 @@
}
if (env_var_value == NULL){
- if (cfg->cookie_samesite == am_samesite_lax) {
+ if ((cfg->cookie_samesite != am_samesite_default) &&
+ (apr_table_get(r->notes, AM_FORCE_SAMESITE_NONE_NOTE) != NULL)) {
+ cookie_samesite = "; SameSite=None";
+ }
+ else if (cfg->cookie_samesite == am_samesite_lax) {
cookie_samesite = "; SameSite=Lax";
} else if (cfg->cookie_samesite == am_samesite_strict) {
cookie_samesite = "; SameSite=Strict";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_diagnostics.c
new/mod_auth_mellon-0.17.0/auth_mellon_diagnostics.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_diagnostics.c 2020-01-14
14:02:57.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_diagnostics.c 2020-09-08
12:52:15.000000000 +0200
@@ -420,7 +420,7 @@
indent(level+1), cfg->varname);
apr_file_printf(diag_cfg->fd,
"%sMellonSecureCookie (secure): %s\n",
- indent(level+1), cfg->secure ? "On":"Off"); /* FIXME,
should be combined? */
+ indent(level+1), cfg->secure ? "On":"Off");
apr_file_printf(diag_cfg->fd,
"%sMellonSecureCookie (httpd_only): %s\n",
indent(level+1), cfg->http_only ? "On":"Off");
@@ -809,9 +809,10 @@
am_diag_cache_key_type_str(am_cache_key_t key_type)
{
switch(key_type) {
- case AM_CACHE_SESSION: return "session";
- case AM_CACHE_NAMEID : return "name id";
- default: return "unknown";
+ case AM_CACHE_SESSION: return "session";
+ case AM_CACHE_NAMEID: return "name id";
+ case AM_CACHE_ASSERTIONID: return "assertion id";
+ default: return "unknown";
}
}
@@ -1108,6 +1109,7 @@
am_req_cfg_rec *req_cfg = am_get_req_cfg(r);
const char *name_id = NULL;
+ const char *assertion_id = NULL;
if (!AM_DIAG_ENABLED(diag_cfg)) return;
if (!am_diag_initialize_req(r, diag_cfg, req_cfg)) return;
@@ -1118,6 +1120,7 @@
if (entry) {
name_id = am_cache_env_fetch_first(entry, "NAME_ID");
+ assertion_id = am_cache_env_fetch_first(entry, "ASSERTION_ID");
apr_file_printf(diag_cfg->fd,
"%skey: %s\n",
@@ -1126,6 +1129,9 @@
"%sname_id: %s\n",
indent(level+1), name_id);
apr_file_printf(diag_cfg->fd,
+ "%sassertion_id: %s\n",
+ indent(level+1), assertion_id);
+ apr_file_printf(diag_cfg->fd,
"%sexpires: %s\n",
indent(level+1),
am_diag_time_t_to_8601(r, entry->expires));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_handler.c
new/mod_auth_mellon-0.17.0/auth_mellon_handler.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_handler.c 2020-01-14
14:01:06.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_handler.c 2020-09-08
12:52:15.000000000 +0200
@@ -817,7 +817,7 @@
*/
static int am_handle_invalidate_request(request_rec *r)
{
- int rc;
+ gint res = 0, rc = HTTP_OK;
char *return_to;
am_cache_entry_t *session = am_get_request_session(r);
am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
@@ -826,7 +826,8 @@
if (cfg->enabled_invalidation_session == 0) {
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
"Session Invalidation Endpoint is not enabled.");
- return HTTP_BAD_REQUEST;
+ rc = HTTP_BAD_REQUEST;
+ goto exit;
}
am_diag_printf(r, "enter function %s\n", __func__);
@@ -837,41 +838,55 @@
if (return_to == NULL) {
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
"No ReturnTo parameter provided for invalidate
handler.");
- return HTTP_BAD_REQUEST;
+ rc = HTTP_BAD_REQUEST;
+ goto exit;
}
/* Check for bad characters in ReturnTo. */
- rc = am_check_url(r, return_to);
- if (rc != OK) {
- return rc;
+ res = am_check_url(r, return_to);
+ if (res != OK) {
+ rc = HTTP_BAD_REQUEST;
+ goto exit;
}
- rc = am_urldecode(return_to);
- if (rc != OK) {
+ res = am_urldecode(return_to);
+ if (res != OK) {
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, rc, r,
"Could not urldecode ReturnTo value in invalidate"
" response.");
- return HTTP_BAD_REQUEST;
+ rc = HTTP_BAD_REQUEST;
+ goto exit;
}
/* Make sure that it is a valid redirect URL. */
- rc = am_validate_redirect_url(r, return_to);
- if (rc != OK) {
+ res = am_validate_redirect_url(r, return_to);
+ if (res != OK) {
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
"Invalid target domain in invalidate response ReturnTo
parameter.");
- return rc;
+ rc = HTTP_BAD_REQUEST;
+ goto exit;
}
if (session == NULL) {
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
"Error processing invalidate request message."
" No session found.");
- } else {
- am_delete_request_session(r, session);
+ rc = HTTP_BAD_REQUEST;
+ goto exit;
}
+ am_delete_request_session(r, session);
+
apr_table_setn(r->headers_out, "Location", return_to);
- return HTTP_SEE_OTHER;
+
+ rc = HTTP_SEE_OTHER;
+
+exit:
+ if (session != NULL) {
+ am_release_request_session(r, session);
+ }
+
+ return rc;
}
/* This function handles a logout response message from the IdP. We get
@@ -1564,6 +1579,42 @@
+/* Validate that the ID of the Assertion has not been used.
+ *
+ * Parameters:
+ * request_rec *r The current request. Used to log
+ * errors.
+ * LassoSaml2Assertion *assertion The assertion we will validate.
+ *
+ * Returns:
+ * OK on success, HTTP_BAD_REQUEST on failure.
+ */
+static int am_validate_unique_assertion_id(request_rec *r,
+ LassoSaml2Assertion *assertion)
+{
+ am_cache_entry_t *session = NULL;
+
+ if (assertion->ID == NULL) {
+ AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
+ "Assertion ID is not present.");
+ return HTTP_BAD_REQUEST;
+ }
+
+ // Check if there is a session associate with the Assertion ID
+ session = am_get_request_session_by_assertionid(r, assertion->ID);
+ if (session != NULL) {
+ am_cache_unlock(r, session);
+ AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
+ "Assertion ID %s has already been used.",
+ assertion->ID);
+ return HTTP_BAD_REQUEST;
+ }
+
+ return OK;
+}
+
+
+
/* This function sets the session expire timestamp based on NotOnOrAfter
* attribute of a condition element.
*
@@ -1663,12 +1714,18 @@
+ apr_time_make(dir_cfg->session_length, 0));
}
- /* Save session information. */
+ /* Save session NAME_ID information. */
ret = am_cache_env_append(session, "NAME_ID", name_id);
if(ret != OK) {
return ret;
}
+ /* Save session ASSERTION_ID information. */
+ ret = am_cache_env_append(session, "ASSERTION_ID", assertion->ID);
+ if(ret != OK) {
+ return ret;
+ }
+
/* Update expires timestamp of session. */
am_handle_session_expire(r, session, assertion);
@@ -1921,6 +1978,13 @@
return rc;
}
+ rc = am_validate_unique_assertion_id(r, assertion);
+
+ if (rc != OK) {
+ lasso_login_destroy(login);
+ return rc;
+ }
+
in_response_to = response->parent.InResponseTo;
@@ -3197,8 +3261,13 @@
/* Add cookie for cookie test. We know that we should have
* a valid cookie when we return from the IdP after SP-initiated
* login.
+ * Ensure that SameSite is set to None for this cookie if SameSite
+ * is allowed to be set as the cookie otherwise gets lost on
+ * HTTP-POST binding messages.
*/
+ apr_table_setn(r->notes, AM_FORCE_SAMESITE_NONE_NOTE, "1");
am_cookie_set(r, "cookietest");
+ apr_table_unset(r->notes, AM_FORCE_SAMESITE_NONE_NOTE);
server = am_get_lasso_server(r);
if(server == NULL) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_httpclient.c
new/mod_auth_mellon-0.17.0/auth_mellon_httpclient.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_httpclient.c 2020-01-14
14:03:08.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_httpclient.c 2020-09-08
12:52:15.000000000 +0200
@@ -1,7 +1,7 @@
/*
*
* mod_auth_mellon.c: an authentication apache module
- * Copyright � 2003-2007 UNINETT (http://www.uninett.no/)
+ * Copyright © 2003-2007 UNINETT (http://www.uninett.no/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -483,6 +483,7 @@
char curl_error[CURL_ERROR_SIZE];
CURLcode res;
struct curl_slist *ctheader;
+ am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
/* Initialize the data storage. */
am_hc_block_header_init(&bh, r->pool);
@@ -537,6 +538,11 @@
NULL
));
+ /* Check if the send expect header is "off". */
+ if (cfg->send_expect_header == 0) {
+ ctheader = curl_slist_append(ctheader, "Expect:");
+ }
+
/* Set headers. */
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, ctheader);
if(res != CURLE_OK) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_session.c
new/mod_auth_mellon-0.17.0/auth_mellon_session.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_session.c 2020-01-14
14:01:03.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_session.c 2020-09-08
12:52:15.000000000 +0200
@@ -1,7 +1,7 @@
/*
*
* auth_mellon_session.c: an authentication apache module
- * Copyright � 2003-2007 UNINETT (http://www.uninett.no/)
+ * Copyright © 2003-2007 UNINETT (http://www.uninett.no/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
*
* Parameters:
* request_rec *r The request we received from the user.
- * am_cache_key_t type AM_CACHE_SESSION or AM_CACHE_NAMEID
+ * am_cache_key_t type AM_CACHE_SESSION, AM_CACHE_NAMEID or
AM_CACHE_ASSERTIONID
* const char *key The session key or user
*
* Returns:
@@ -108,6 +108,21 @@
return am_lock_and_validate(r, AM_CACHE_NAMEID, nameid);
}
+/* This function gets the session associated with a user, using the Assertion
ID
+ *
+ * Parameters:
+ * request_rec *r The request we received from the user.
+ * char *assertionid The AssertionID
+ *
+ * Returns:
+ * The session associated with the user who places the request, or
+ * NULL if we don't have a session yet.
+ */
+am_cache_entry_t *am_get_request_session_by_assertionid(request_rec *r, char
*assertionid)
+{
+ return am_lock_and_validate(r, AM_CACHE_ASSERTIONID, assertionid);
+}
+
/* This function creates a new session.
*
* Parameters:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/auth_mellon_util.c
new/mod_auth_mellon-0.17.0/auth_mellon_util.c
--- old/mod_auth_mellon-0.16.0/auth_mellon_util.c 2020-01-14
14:01:03.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/auth_mellon_util.c 2020-09-08
12:52:15.000000000 +0200
@@ -232,7 +232,7 @@
/*
* Make sure we got a %
*/
- assert(instr[i] == '%');
+ assert(instr[i] == '%');
/*
* Copy the format string in fstr. It can be a single
@@ -393,7 +393,7 @@
am_diag_cond_str(r, ce));
/*
- * Rule with ignore flog?
+ * Rule with ignore flag?
*/
if (ce->flags & AM_COND_FLAG_IGN)
continue;
@@ -449,7 +449,7 @@
value = am_cache_entry_get_string(session, &session->env[j].value);
/*
- * Substiture backrefs if available
+ * Substitute backrefs if available
*/
if (ce->flags & AM_COND_FLAG_FSTR)
ce = am_cond_substitue(r, ce, backrefs);
@@ -463,7 +463,7 @@
if (value == NULL) {
match = 0; /* can not happen */
- } else if (ce->flags & (AM_COND_FLAG_REG|AM_COND_FLAG_REF)) {
+ } else if ((ce->flags & AM_COND_FLAG_REG) && (ce->flags &
AM_COND_FLAG_REF)) {
int nsub = ce->regex->re_nsub + 1;
ap_regmatch_t *regmatch;
@@ -477,11 +477,11 @@
} else if (ce->flags & AM_COND_FLAG_REG) {
match = !ap_regexec(ce->regex, value, 0, NULL, 0);
- } else if (ce->flags & (AM_COND_FLAG_SUB|AM_COND_FLAG_NC)) {
- match = (ap_strcasestr(ce->str, value) != NULL);
+ } else if ((ce->flags & AM_COND_FLAG_SUB) && (ce->flags &
AM_COND_FLAG_NC)) {
+ match = (ap_strcasestr(value, ce->str) != NULL);
} else if (ce->flags & AM_COND_FLAG_SUB) {
- match = (strstr(ce->str, value) != NULL);
+ match = (strstr(value, ce->str) != NULL);
} else if (ce->flags & AM_COND_FLAG_NC) {
match = !strcasecmp(ce->str, value);
@@ -490,7 +490,7 @@
match = !strcmp(ce->str, value);
}
- am_diag_printf(r, "match=%s, ", match ? "yes" : "no");
+ am_diag_printf(r, "match=%s, ", match ? "yes" : "no");
}
if (ce->flags & AM_COND_FLAG_NOT) {
@@ -1786,7 +1786,7 @@
AM_LOG_RERROR(APLOG_MARK, APLOG_WARNING, 0, r,
"Cannot find provider service %s, no provider.",
service_name);
- return NULL;
+ return NULL;
}
url = lasso_provider_get_metadata_one(provider, service_name);
@@ -1794,7 +1794,7 @@
AM_LOG_RERROR(APLOG_MARK, APLOG_WARNING, 0, r,
"Cannot find provider service %s from metadata.",
service_name);
- return NULL;
+ return NULL;
}
return url;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/configure
new/mod_auth_mellon-0.17.0/configure
--- old/mod_auth_mellon-0.16.0/configure 2020-01-28 16:06:03.000000000
+0100
+++ new/mod_auth_mellon-0.17.0/configure 2020-09-08 12:52:22.000000000
+0200
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for mod_auth_mellon 0.16.0.
+# Generated by GNU Autoconf 2.69 for mod_auth_mellon 0.17.0.
#
# Report bugs to <https://github.com/latchset/mod_auth_mellon/issues>.
#
@@ -581,8 +581,8 @@
# Identity of this package.
PACKAGE_NAME='mod_auth_mellon'
PACKAGE_TARNAME='mod_auth_mellon'
-PACKAGE_VERSION='0.16.0'
-PACKAGE_STRING='mod_auth_mellon 0.16.0'
+PACKAGE_VERSION='0.17.0'
+PACKAGE_STRING='mod_auth_mellon 0.17.0'
PACKAGE_BUGREPORT='https://github.com/latchset/mod_auth_mellon/issues'
PACKAGE_URL=''
@@ -667,6 +667,7 @@
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -750,6 +751,7 @@
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1002,6 +1004,15 @@
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1139,7 +1150,7 @@
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1252,7 +1263,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures mod_auth_mellon 0.16.0 to adapt to many kinds of
systems.
+\`configure' configures mod_auth_mellon 0.17.0 to adapt to many kinds of
systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1292,6 +1303,7 @@
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1313,7 +1325,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of mod_auth_mellon 0.16.0:";;
+ short | recursive ) echo "Configuration of mod_auth_mellon 0.17.0:";;
esac
cat <<\_ACEOF
@@ -1420,7 +1432,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-mod_auth_mellon configure 0.16.0
+mod_auth_mellon configure 0.17.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1768,7 +1780,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by mod_auth_mellon $as_me 0.16.0, which was
+It was created by mod_auth_mellon $as_me 0.17.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3087,7 +3099,7 @@
-NAMEVER=mod_auth_mellon-0.16.0
+NAMEVER=mod_auth_mellon-0.17.0
@@ -3346,8 +3358,8 @@
fi
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LASSO" >&5
-$as_echo_n "checking for LASSO... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lasso" >&5
+$as_echo_n "checking for lasso... " >&6; }
if test -n "$LASSO_CFLAGS"; then
pkg_cv_LASSO_CFLAGS="$LASSO_CFLAGS"
@@ -3387,7 +3399,7 @@
if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -3414,7 +3426,7 @@
and LASSO_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
@@ -3612,8 +3624,8 @@
# We need the curl library for HTTP-Artifact downloads.
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CURL" >&5
-$as_echo_n "checking for CURL... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcurl" >&5
+$as_echo_n "checking for libcurl... " >&6; }
if test -n "$CURL_CFLAGS"; then
pkg_cv_CURL_CFLAGS="$CURL_CFLAGS"
@@ -3653,7 +3665,7 @@
if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -3680,7 +3692,7 @@
and CURL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
@@ -3707,8 +3719,8 @@
# We also need openssl for its random number generator.
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL" >&5
-$as_echo_n "checking for OPENSSL... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl" >&5
+$as_echo_n "checking for openssl... " >&6; }
if test -n "$OPENSSL_CFLAGS"; then
pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS"
@@ -3748,7 +3760,7 @@
if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -3775,7 +3787,7 @@
and OPENSSL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
@@ -3802,8 +3814,8 @@
# We need at least version 2.12 of GLib.
pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB" >&5
-$as_echo_n "checking for GLIB... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glib-2.0 >= 2.12" >&5
+$as_echo_n "checking for glib-2.0 >= 2.12... " >&6; }
if test -n "$GLIB_CFLAGS"; then
pkg_cv_GLIB_CFLAGS="$GLIB_CFLAGS"
@@ -3843,7 +3855,7 @@
if test $pkg_failed = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@@ -3870,7 +3882,7 @@
and GLIB_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
@@ -4868,7 +4880,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by mod_auth_mellon $as_me 0.16.0, which was
+This file was extended by mod_auth_mellon $as_me 0.17.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4930,7 +4942,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //;
s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-mod_auth_mellon config.status 0.16.0
+mod_auth_mellon config.status 0.17.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/configure.ac
new/mod_auth_mellon-0.17.0/configure.ac
--- old/mod_auth_mellon-0.16.0/configure.ac 2020-01-28 15:59:44.000000000
+0100
+++ new/mod_auth_mellon-0.17.0/configure.ac 2020-09-08 12:52:15.000000000
+0200
@@ -1,4 +1,4 @@
-AC_INIT([mod_auth_mellon],[0.16.0],[https://github.com/latchset/mod_auth_mellon/issues])
+AC_INIT([mod_auth_mellon],[0.17.0],[https://github.com/latchset/mod_auth_mellon/issues])
AC_CONFIG_HEADERS([config.h])
# We require support for C99.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/doc/mellon_create_metadata.8
new/mod_auth_mellon-0.17.0/doc/mellon_create_metadata.8
--- old/mod_auth_mellon-0.16.0/doc/mellon_create_metadata.8 2020-01-28
15:59:44.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/doc/mellon_create_metadata.8 2020-09-08
12:52:15.000000000 +0200
@@ -1,6 +1,6 @@
.TH man 8 "25 January 2020" "1.0" "mellon_create_metadata manual page"
.SH NAME
-mellon_create_metadata \- Populate inital SP metadata for mod_auth_mellon
+mellon_create_metadata \- Populate initial SP metadata for mod_auth_mellon
.SH SYNOPSIS
mellon_create_metadata ENTITY-ID ENDPOINT-URL
.SH DESCRIPTION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/mellon_create_metadata.sh
new/mod_auth_mellon-0.17.0/mellon_create_metadata.sh
--- old/mod_auth_mellon-0.16.0/mellon_create_metadata.sh 2020-01-28
15:59:44.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/mellon_create_metadata.sh 2020-09-08
12:52:15.000000000 +0200
@@ -57,7 +57,7 @@
cat >"$TEMPLATEFILE" <<EOF
RANDFILE = /dev/urandom
[req]
-default_bits = 2048
+default_bits = 3072
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
prompt = no
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mod_auth_mellon-0.16.0/mod_auth_mellon.c
new/mod_auth_mellon-0.17.0/mod_auth_mellon.c
--- old/mod_auth_mellon-0.16.0/mod_auth_mellon.c 2020-01-14
14:01:03.000000000 +0100
+++ new/mod_auth_mellon-0.17.0/mod_auth_mellon.c 2020-09-08
12:52:15.000000000 +0200
@@ -1,7 +1,7 @@
/*
*
* mod_auth_mellon.c: an authentication apache module
- * Copyright � 2003-2007 UNINETT (http://www.uninett.no/)
+ * Copyright © 2003-2007 UNINETT (http://www.uninett.no/)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by