From fe2ddab0470e0189f06df51a70a5e1ac8d94322a Mon Sep 17 00:00:00 2001 From: Ian Young Date: Tue, 29 Aug 2017 10:56:40 +0100 Subject: [PATCH 01/63] Remove checks for consistent certificate alternative names This was needed circa 2013 to guard against a curl-based issue in the Shibboleth SP. This can no longer affect us because we no longer use the PKIX trust model. --- mdx/uk/beans.xml | 2 -- mdx/uk/verbs.xml | 2 -- 2 files changed, 4 deletions(-) diff --git a/mdx/uk/beans.xml b/mdx/uk/beans.xml index 22b88e63..26c0166d 100644 --- a/mdx/uk/beans.xml +++ b/mdx/uk/beans.xml @@ -306,8 +306,6 @@ p:warningBoundary="0" p:errorBoundary="2048"/> - - - - + + + + + + + + + + + + + + - + diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index 0c679ef1..4f140d1c 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -53,13 +53,7 @@ final tweaks on the document. --> - - - - - - + p:XSLResource="classpath:uk/final_tweak.xsl"/> Date: Thu, 14 Sep 2017 11:08:06 +0100 Subject: [PATCH 03/63] set validUntil using the available MDA stage instead of XSLT See ukf/ukf-meta#145. --- build.xml | 1 + mdx/uk/final_tweak.xsl | 20 +++++++------------- mdx/uk/generate.xml | 41 ++++++++++++++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/build.xml b/build.xml index 071c2607..620e48d5 100644 --- a/build.xml +++ b/build.xml @@ -1471,6 +1471,7 @@ + - - - - - + + + - - - - + + + + U K F E D E R A T I O N M E T A D A T A diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index 4f140d1c..76bfad38 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -37,6 +37,19 @@ ***************************** --> + + + + + + + + + + + + + + + + + + + + + + - + @@ -516,7 +543,7 @@ - + @@ -571,7 +598,7 @@ - + @@ -696,7 +723,7 @@ - + @@ -812,7 +839,7 @@ - + From 90d95ecab0b9abfa355d0129bad315b83827b837 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 14 Sep 2017 11:44:19 +0100 Subject: [PATCH 04/63] Centralise setting of ID attribute on aggregates --- mdx/uk/generate.xml | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index 76bfad38..e1aa2d14 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -71,13 +71,23 @@ + + + + + + @@ -101,17 +111,6 @@ - - - - - - - @@ -373,7 +371,6 @@ - @@ -492,7 +489,6 @@ - @@ -546,7 +542,6 @@ - @@ -601,7 +596,6 @@ - @@ -727,7 +721,6 @@ - @@ -843,7 +836,6 @@ - From 0b11c91f515b1b6ae5e46c99cc2b3ada89ffcad8 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Fri, 29 Sep 2017 15:24:35 +0100 Subject: [PATCH 05/63] Refresh list of federations and their registrationAuthority URLs as per eduGAIN Members page --- mdx/common-beans.xml | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index bf13de14..8c64240c 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -284,17 +284,20 @@ - + + + + @@ -306,6 +309,7 @@ + @@ -318,14 +322,17 @@ - + + + + @@ -354,9 +361,12 @@ http://www.edugain.org/technical/status.php --> + + + @@ -385,6 +395,7 @@ + @@ -398,12 +409,15 @@ - - + + - + + + + From 63956416839f1881cff24d8fced1f787ef5c7d8f Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 2 Oct 2017 11:32:53 +0100 Subject: [PATCH 06/63] Fix spacing in charting statistics --- mdx/uk/statistics-charting.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdx/uk/statistics-charting.xsl b/mdx/uk/statistics-charting.xsl index c8cf91fe..0f7a5af8 100644 --- a/mdx/uk/statistics-charting.xsl +++ b/mdx/uk/statistics-charting.xsl @@ -144,7 +144,7 @@ - Algorithm support: + Algorithm support: of SP entities From 32c1a74912c8c39613cc51fcc13e16609660217a Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Thu, 12 Oct 2017 17:28:17 +0100 Subject: [PATCH 07/63] Update slack channel that Ant (on aggr) posts to in build.xml. --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 620e48d5..f78f4b75 100644 --- a/build.xml +++ b/build.xml @@ -1615,7 +1615,7 @@ - From 78d613dde1368dcf7eb06fc3dadec3ba0a338891 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Fri, 13 Oct 2017 10:05:22 +0100 Subject: [PATCH 08/63] Update slack channel that daily stats get set to --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index f78f4b75..040c5ef1 100644 --- a/build.xml +++ b/build.xml @@ -1153,7 +1153,7 @@ - From 6388bffd681ae8d601c4dd031b95e4ffcc18473e Mon Sep 17 00:00:00 2001 From: Jon Agland Date: Fri, 13 Oct 2017 14:15:41 +0100 Subject: [PATCH 09/63] Add utilities/contacts-from-sf.sh for processing Salesforce contact data. --- utilities/contacts-from-sf.sh | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100755 utilities/contacts-from-sf.sh diff --git a/utilities/contacts-from-sf.sh b/utilities/contacts-from-sf.sh new file mode 100755 index 00000000..18fb219e --- /dev/null +++ b/utilities/contacts-from-sf.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# This script processes a Salesforce report "UKfed-contacts-export" which lists all contacts with +# UK Federation Contact Roles and their corresponding Jisc Organisation ID (ukforg) and Organisation Name +# +# The current report can be found here https://eu3.salesforce.com/00Ow0000007MXhK, it needs to be exported as a CSV file +# which ends up as 'reportnnnnnnnnnnnnn.csv' +# +# The input to the script is the above CSV file. +# +# The output of the script is as follows; +# +# * A copy of the Salesforce report in $CSVDEST +# * A list of Management Contact email addresses in $MGMTDEST +# * A list of all contact email addresses in $CONTACTDEST +# +# To use this script please follow the process here; +# +# https://repo.infr.ukfederation.org.uk/ukf/ukf-systems/wikis/HOW-to-process-UKfed-contacts-export-report +# +# Author: Jon Agland +# + +SFREPORTNAME="UKfed-contacts-export" +CSVDEST=../../ukf-data/contacts/sf-contacts.csv +CONTACTDEST=../../ukf-data/contacts/sf-contacts.txt +MGMTDEST=../../ukf-data/contacts/sf-contacts-mc.txt + +if [ -z "$1" ]; then + echo "ERROR: No file name supplied" + exit 1 +fi + +if [ ! -f "$1" ]; then + echo "ERROR: file $1 does not exist" + exit 1 +fi + +if ! grep -q \"$SFREPORTNAME\" $1; then + echo "ERROR: this doesn't appear to be the output of $SFREPORTNAME" + exit 2 +fi + +cat $1 | awk -F\, '{ print $1 }' | grep @ | sed -e 's/\"//g' | sort -u > $CONTACTDEST +grep "\,\"UK Federation Management Contact\"" $1 | awk -F\, '{ print $1 }' | grep @ | sed -e 's/\"//g' | sort -u > $MGMTDEST + +cp $1 $CSVDEST + From df0f5987101e8238b14cd686646ff4533109821b Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Fri, 13 Oct 2017 15:34:06 +0100 Subject: [PATCH 10/63] Add utilities/list_addresses.pl to generate list of email addresses See ukf/ukf-meta#146 --- utilities/list_addresses.pl | 138 ++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100755 utilities/list_addresses.pl diff --git a/utilities/list_addresses.pl b/utilities/list_addresses.pl new file mode 100755 index 00000000..55f854e6 --- /dev/null +++ b/utilities/list_addresses.pl @@ -0,0 +1,138 @@ +#!/usr/bin/perl -w +# +# Script to extract technical and administrative contact email addresses +# from a SAML metadata file, and add extra addresses from a well-known location. +# +# Author: Alex Stuart, alex.stuart@jisc.ac.uk +# + +# +# Parameters +# +$metadata = '../mdx/uk/collected.xml'; +$extra_addresses = '../../ukf-data/members/extra_addresses.txt'; + +# +# Subroutines +# +use Getopt::Long; +use XML::LibXML; + +sub usage { + print <] + + -h - prints this help text and exits + -f - takes metadata from this file, not the pre-defined file. + --security - also extract the security contacts + + Extracts email addresses of contacts in a metadata file. + + By default, this extracts the technical and administrative contacts + from the metadata file, and includes extra addresses. + +EOF +} + +# +# Options processing +# +my $help; +my $file; +my $security; +GetOptions( "help" => \$help, + "file=s" => \$file, + "security" => \$security + ); + +if ( $help ) { + usage(); + exit 0; +} + +if ( $file ) { + $metadata = $file; +} + +if ( ! $metadata ) { + print "ERROR: could not find metadata file $metadata\n"; + usage(); + exit 1; +} + +if ( ! -r $metadata ) { + print "ERROR: metadata file $metadata must be readable\n"; + usage(); + exit 2; +} + + +# +# Extract addresses from metadata file +# +my $dom = XML::LibXML->load_xml( location => $metadata ); +my $xpc = XML::LibXML::XPathContext->new( $dom ); +$xpc->registerNs( 'md', 'urn:oasis:names:tc:SAML:2.0:metadata' ); +@tech_contacts = $xpc->findnodes( '//md:EntityDescriptor/md:ContactPerson/md:EmailAddress[../@contactType="technical"]'); +foreach( @tech_contacts ) { + $email = ${_}->to_literal; + $email =~ s/^mailto://i; + $metadata{$email} = 1; +} + + +@admin_contacts = $xpc->findnodes( '//md:EntityDescriptor/md:ContactPerson/md:EmailAddress[../@contactType="administrative"]'); +foreach( @admin_contacts ) { + $email = ${_}->to_literal; + $email =~ s/^mailto://i; + $metadata{$email} = 1; +} + +if ( $security ) { + $xpc->registerNs( 'remd', 'http://refeds.org/metadata' ); + @security_contacts = $xpc->findnodes( '//md:EntityDescriptor/md:ContactPerson/md:EmailAddress + [../@contactType="other"] + [../@remd:contactType="http://refeds.org/metadata/contactType/security"]' + ); + foreach( @security_contacts ) { + $email = ${_}->to_literal; + $email =~ s/^mailto://i; + $metadata{$email} = 1; + } +} + +# +# Load extra addresses. +# +# One extra address per line. Blank lines and lines starting with '#' are +# ignored. +# +open(EXTRAS, "$extra_addresses") || die "could not open extra addresses file $extra_addresses"; +while () { + chomp; # remove \n + next if /^#/; + $extras{$_} = 1 unless $_ eq ''; +} +close EXTRAS; + +# +# Now figure out the addresses we want to see in the mailing list. +# Make them lower case for comparisons. +# +foreach $addr (keys %extras) { + $wanted{lc $addr} = $addr; +} +foreach $addr (keys %metadata) { + $wanted{lc $addr} = $addr; +} + +# +# List all wanted addresses. +# +print "--- LIST BEGIN ---\n"; +foreach $addr (sort keys %wanted) { + my $a = $wanted{$addr}; + print "$a\n"; +} +print "--- LIST END ---\n"; From 1693bdc75fc05a57f868d94f6271fbab0c716b07 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Fri, 13 Oct 2017 17:14:33 +0100 Subject: [PATCH 11/63] Allow list_addresses.pl to incorporate MC email addresses. See ukf/ukf-meta#146 --- utilities/list_addresses.pl | 38 ++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/utilities/list_addresses.pl b/utilities/list_addresses.pl index 55f854e6..ca5191f2 100755 --- a/utilities/list_addresses.pl +++ b/utilities/list_addresses.pl @@ -9,9 +9,16 @@ # # Parameters # + +# An EntitiesDescriptor of all UKF-registered entities $metadata = '../mdx/uk/collected.xml'; + +# A file of email addresses for people who have opted-in to the list $extra_addresses = '../../ukf-data/members/extra_addresses.txt'; +# Default list of contacts from Salesforce, processed by contacts-from-sf.sh +$sf_contacts = '../../ukf-data/contacts/sf-contacts-mc.txt'; + # # Subroutines # @@ -21,11 +28,13 @@ sub usage { print <] + $0 [-h] [-f ] [--security] [--mc] [-c ] - -h - prints this help text and exits - -f - takes metadata from this file, not the pre-defined file. - --security - also extract the security contacts + -h - prints this help text and exits + -f - takes metadata from this file, not the pre-defined file + --security - also extract the security contacts + --mc - add Management Contacts from a well-known location + -c - Use this contacts file not the well-known location Extracts email addresses of contacts in a metadata file. @@ -41,9 +50,13 @@ sub usage { my $help; my $file; my $security; +my $mc; +my $contacts = $sf_contacts; GetOptions( "help" => \$help, "file=s" => \$file, - "security" => \$security + "security" => \$security, + "mc" => \$mc, + "c:s" => \$contacts ); if ( $help ) { @@ -127,6 +140,21 @@ sub usage { $wanted{lc $addr} = $addr; } +# +# And if we want to include Management Contact emails too +# +if ( $mc ) { + open(SFCONTACTS, "$contacts") || die "could not open contacts file $contacts"; + while () { + chomp; + $sfcontacts{$_} = 1 unless $_ eq ''; + } + close SFCONTACTS; + foreach $addr (keys %sfcontacts) { + $wanted{lc $addr} = $addr; + } +} + # # List all wanted addresses. # From ffac2b8e5d3d69d44e4d3cfe44165141ebd84f34 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Wed, 18 Oct 2017 15:03:47 +0100 Subject: [PATCH 12/63] Add checks for ROCA-vulnerable RSA keys --- mdx/common-beans.xml | 2 ++ mdx/uk/beans.xml | 2 ++ mdx/uk/verbs.xml | 2 ++ .../{ukf-mda-0.9.5.jar => ukf-mda-0.9.6.jar} | Bin 55752 -> 59056 bytes 4 files changed, 6 insertions(+) rename tools/ukf-mda/{ukf-mda-0.9.5.jar => ukf-mda-0.9.6.jar} (75%) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index 8c64240c..eb0832ab 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -1037,6 +1037,8 @@ p:warningBoundary="0" p:errorBoundary="2048"/> + + + + + + - - + diff --git a/mdx/uk/beans.xml b/mdx/uk/beans.xml index 5325f593..2e912136 100644 --- a/mdx/uk/beans.xml +++ b/mdx/uk/beans.xml @@ -302,10 +302,10 @@ - - + diff --git a/mdx/uk/verbs.xml b/mdx/uk/verbs.xml index 26e990cc..6d066051 100644 --- a/mdx/uk/verbs.xml +++ b/mdx/uk/verbs.xml @@ -310,10 +310,10 @@ - - + From 4a9c79ade721a125e5cc7badf59d8b8a48e0753f Mon Sep 17 00:00:00 2001 From: Ian Young Date: Sat, 21 Oct 2017 17:40:10 +0100 Subject: [PATCH 14/63] Remove xsi:type from imported entity attribute values See ukf/ukf-meta#147. --- mdx/uk/import.xsl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mdx/uk/import.xsl b/mdx/uk/import.xsl index 900cd105..8c557668 100644 --- a/mdx/uk/import.xsl +++ b/mdx/uk/import.xsl @@ -316,6 +316,17 @@ + + + + + + + + + + From 78f9200044989f79d2ceb72e142e813d8e762297 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Wed, 25 Oct 2017 09:28:51 +0100 Subject: [PATCH 16/63] Update build process to use new path locations on web servers --- build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index 040c5ef1..d9e37551 100644 --- a/build.xml +++ b/build.xml @@ -194,8 +194,8 @@ --> - - + + From 52c3b3ec8efbe1f96564da4825d086a6a7ed2161 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Wed, 25 Oct 2017 15:57:48 +0100 Subject: [PATCH 17/63] Populate UKf MDUI DisplayName in test, export-preview aggregates See ukf/ukf-meta#21. --- mdx/uk/README.md | 10 ++-- mdx/uk/generate.xml | 52 +++++++++++++++++++++ mdx/uk/odn_to_mdui.xsl | 102 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 mdx/uk/odn_to_mdui.xsl diff --git a/mdx/uk/README.md b/mdx/uk/README.md index 88b4703b..8531bd91 100644 --- a/mdx/uk/README.md +++ b/mdx/uk/README.md @@ -28,9 +28,10 @@ before being included in the `export` version consumed by interfederation partne ### Export Preview Aggregate vs. Export Aggregate -Status (2017-02-14): +Status (2017-10-25): -* These aggregates are currently identical. +* The export preview aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` +metadata by copying data from `md:OrganizationDisplayName` if required. ## Production Maturity Pipeline @@ -59,9 +60,10 @@ when it appeared in the fallback aggregate, which would be too late to take corr ### Test Aggregate vs. Production Aggregate -Status (2017-03-02): +Status (2017-10-25): -* These aggregates are currently identical. +* The test aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` +metadata by copying data from `md:OrganizationDisplayName` if required. ### Fallback Aggregate vs. Production Aggregate diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index e1aa2d14..277887e5 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -112,6 +112,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -825,6 +871,12 @@ + + + diff --git a/mdx/uk/odn_to_mdui.xsl b/mdx/uk/odn_to_mdui.xsl new file mode 100644 index 00000000..55576407 --- /dev/null +++ b/mdx/uk/odn_to_mdui.xsl @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6a1ef6b95bf0668249a10490d765efef287fd8c6 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Fri, 27 Oct 2017 13:07:05 +0100 Subject: [PATCH 18/63] Remove header and footer in output from list_addresses.pl See ukf/ukf-meta#149 --- utilities/list_addresses.pl | 2 -- 1 file changed, 2 deletions(-) diff --git a/utilities/list_addresses.pl b/utilities/list_addresses.pl index ca5191f2..77841152 100755 --- a/utilities/list_addresses.pl +++ b/utilities/list_addresses.pl @@ -158,9 +158,7 @@ sub usage { # # List all wanted addresses. # -print "--- LIST BEGIN ---\n"; foreach $addr (sort keys %wanted) { my $a = $wanted{$addr}; print "$a\n"; } -print "--- LIST END ---\n"; From 4e49454fb31919ee8c3e77cd77bb52254981eda4 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 6 Nov 2017 18:07:13 +0000 Subject: [PATCH 19/63] Reorganize and comment for clarity --- mdx/uk/beans.xml | 147 +++++++++++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 51 deletions(-) diff --git a/mdx/uk/beans.xml b/mdx/uk/beans.xml index 2e912136..66ed49e0 100644 --- a/mdx/uk/beans.xml +++ b/mdx/uk/beans.xml @@ -12,6 +12,68 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> + + + + + + + + + + + + + administrative + + + + + + + + + + + + + + + + + + + + + + @@ -102,26 +164,12 @@ - - - - - - - - - - - - - - - - - - - administrative - - - - + - - + uk_fetchFragmentFiles - - - - - + + + + + + + + + + + - From caa39fa2e0b69e5052b0deed0b0e3ad304df77a9 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Tue, 7 Nov 2017 10:55:48 +0000 Subject: [PATCH 20/63] Move two UKf-only checks into the uk directory --- mdx/uk/beans.xml | 26 +++++++++++++++++-- .../check_uk_mdui_dn_en_match.xsl} | 4 +-- .../check_uk_mdui_dn_en_present.xsl} | 4 +-- mdx/validation-beans.xml | 26 ------------------- 4 files changed, 28 insertions(+), 32 deletions(-) rename mdx/{_rules/mdui_dn_en_match.xsl => uk/check_uk_mdui_dn_en_match.xsl} (93%) rename mdx/{_rules/mdui_dn_en_present.xsl => uk/check_uk_mdui_dn_en_present.xsl} (90%) diff --git a/mdx/uk/beans.xml b/mdx/uk/beans.xml index 66ed49e0..38cb1cfa 100644 --- a/mdx/uk/beans.xml +++ b/mdx/uk/beans.xml @@ -261,6 +261,28 @@ p:XSLResource="classpath:uk/check_uk_urlenc.xsl"/> + + + + + + + + - + diff --git a/mdx/_rules/mdui_dn_en_present.xsl b/mdx/uk/check_uk_mdui_dn_en_present.xsl similarity index 90% rename from mdx/_rules/mdui_dn_en_present.xsl rename to mdx/uk/check_uk_mdui_dn_en_present.xsl index e5364e11..b8d11d36 100644 --- a/mdx/_rules/mdui_dn_en_present.xsl +++ b/mdx/uk/check_uk_mdui_dn_en_present.xsl @@ -1,7 +1,7 @@ - + diff --git a/mdx/validation-beans.xml b/mdx/validation-beans.xml index f7ed527f..980bd328 100644 --- a/mdx/validation-beans.xml +++ b/mdx/validation-beans.xml @@ -220,36 +220,10 @@ - - - - - - From 9c7b0c50066c2358fde08723a7803750b50182fe Mon Sep 17 00:00:00 2001 From: Ian Young Date: Tue, 7 Nov 2017 15:10:41 +0000 Subject: [PATCH 21/63] Add mdui:Description to generated IdP mdui:UIInfo Iterate on the generation of mdui:UIInfo for identitify providers which do not have mdui:UIInfo already. Reduces the number of warnings we get from the eduGAIN validator. See ukf/ukf-meta#150. --- mdx/uk/README.md | 6 ++++-- mdx/uk/odn_to_mdui.xsl | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/mdx/uk/README.md b/mdx/uk/README.md index 8531bd91..bbb609e0 100644 --- a/mdx/uk/README.md +++ b/mdx/uk/README.md @@ -31,7 +31,8 @@ before being included in the `export` version consumed by interfederation partne Status (2017-10-25): * The export preview aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` -metadata by copying data from `md:OrganizationDisplayName` if required. +metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also +generates `mdui:Description` elements with the same content. ## Production Maturity Pipeline @@ -63,7 +64,8 @@ when it appeared in the fallback aggregate, which would be too late to take corr Status (2017-10-25): * The test aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` -metadata by copying data from `md:OrganizationDisplayName` if required. +metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also +generates `mdui:Description` elements with the same content. ### Fallback Aggregate vs. Production Aggregate diff --git a/mdx/uk/odn_to_mdui.xsl b/mdx/uk/odn_to_mdui.xsl index 55576407..6512cb8b 100644 --- a/mdx/uk/odn_to_mdui.xsl +++ b/mdx/uk/odn_to_mdui.xsl @@ -4,7 +4,8 @@ odn_to_mdui.xsl If an identity provider does not have at least one MDUI-based discovery - name, give it one by copying data from its md:OrganizationDisplayName. + name, give it mdui:DisplayName and mdui:Description by copying data from + its md:OrganizationDisplayName. This transform will only be applied to UKf-registered entities. @@ -39,8 +40,8 @@ Match the md:IDPSSODescriptor/md:Extensions element of an identity provider which does not have mdui:UIInfo. - We must fabricate the mdui:UIInfo as well as the mdui:DisplayName - elements. + We must fabricate the mdui:UIInfo as well as the mdui:DisplayName and + mdui:Description elements. --> @@ -57,8 +58,8 @@ + @@ -75,6 +77,16 @@ + + + + + + + + + + From 3e9c90f38c469c7867666d52769257c619129066 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Wed, 8 Nov 2017 11:26:25 +0000 Subject: [PATCH 22/63] Update list of registrars and country codes --- mdx/common-beans.xml | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index 1bd29473..3b7da05a 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -323,24 +323,33 @@ + + + + + + + + - + + @@ -392,6 +401,7 @@ + @@ -406,6 +416,7 @@ + @@ -417,14 +428,21 @@ + + - + + - - + + + + + + From 7e6a22e1d51c51d7723b9cfa33e875dc30ccca27 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Wed, 8 Nov 2017 11:48:00 +0000 Subject: [PATCH 23/63] Update path on webserver to copy members file to --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index d9e37551..ad2c509b 100644 --- a/build.xml +++ b/build.xml @@ -195,7 +195,7 @@ - + From 9b6c6de4b3f11e1ea67d4e3fb15ab1cd5719aeeb Mon Sep 17 00:00:00 2001 From: Ian Young Date: Wed, 22 Nov 2017 15:48:28 +0000 Subject: [PATCH 24/63] Populate UKf MDUI DisplayName,Description in cdsall aggregates See ukf/ukf-meta#21. --- mdx/uk/README.md | 10 +++++++++- mdx/uk/generate.xml | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mdx/uk/README.md b/mdx/uk/README.md index bbb609e0..f42cc312 100644 --- a/mdx/uk/README.md +++ b/mdx/uk/README.md @@ -67,9 +67,17 @@ Status (2017-10-25): metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also generates `mdui:Description` elements with the same content. +### `cds-all` Aggregate vs. Production Aggregate + +Status (2017-11-22): + +* The `cds-all` aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` + metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also + generates `mdui:Description` elements with the same content. + ### Fallback Aggregate vs. Production Aggregate Status (2017-03-14): -* the production aggregate implements a _blacklisting_ approach to entity attributes imported from eduGAIN, +* The production aggregate implements a _blacklisting_ approach to entity attributes imported from eduGAIN, while the production aggregate implements the traditional entity attribute _whitelist_. (2017-03-02) diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index 277887e5..92fcf779 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -509,6 +509,12 @@ + + + From 083fef980b4df6080c1d2dfdfad5c7c71c72b73e Mon Sep 17 00:00:00 2001 From: Ian Young Date: Fri, 24 Nov 2017 11:39:18 +0000 Subject: [PATCH 25/63] Restrospective update to aggregate status in README --- mdx/uk/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mdx/uk/README.md b/mdx/uk/README.md index f42cc312..4d4491f2 100644 --- a/mdx/uk/README.md +++ b/mdx/uk/README.md @@ -77,7 +77,6 @@ Status (2017-11-22): ### Fallback Aggregate vs. Production Aggregate -Status (2017-03-14): +Status (2017-04-10): -* The production aggregate implements a _blacklisting_ approach to entity attributes imported from eduGAIN, -while the production aggregate implements the traditional entity attribute _whitelist_. (2017-03-02) +* These aggregates are currently identical. From d42223db47433d0ac7a91d16a11b14056f0af188 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Tue, 5 Dec 2017 15:08:19 +0000 Subject: [PATCH 26/63] Populate UKf MDUI DisplayName,Description in production, wayf and export aggregates See ukf/ukf-meta#21. See ukf/ukf-meta#150. --- mdx/uk/README.md | 29 +++++++++++++++-------------- mdx/uk/generate.xml | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/mdx/uk/README.md b/mdx/uk/README.md index 4d4491f2..1cb3bfc2 100644 --- a/mdx/uk/README.md +++ b/mdx/uk/README.md @@ -28,11 +28,9 @@ before being included in the `export` version consumed by interfederation partne ### Export Preview Aggregate vs. Export Aggregate -Status (2017-10-25): +Status (2017-12-05): -* The export preview aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` -metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also -generates `mdui:Description` elements with the same content. +* These aggregates are currently identical. ## Production Maturity Pipeline @@ -61,22 +59,25 @@ when it appeared in the fallback aggregate, which would be too late to take corr ### Test Aggregate vs. Production Aggregate -Status (2017-10-25): +Status (2017-12-05): + +* The `test` aggregate does not include the `` label (`ukf-meta#34`). -* The test aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` -metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also -generates `mdui:Description` elements with the same content. +* The `test` aggregate does not include the entity-level copy of the scopes for an + identity provider (`ukf-meta#49`) ### `cds-all` Aggregate vs. Production Aggregate -Status (2017-11-22): +Status (2017-12-05): -* The `cds-all` aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` - metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also - generates `mdui:Description` elements with the same content. +* The `cdsall` aggregate omits many elements not necessary for the generation of a discovery feed. + +* Otherwise, these aggregates are currently identical. ### Fallback Aggregate vs. Production Aggregate -Status (2017-04-10): +Status (2017-12-05): -* These aggregates are currently identical. +* The production aggregate ensures that all UKf-registered identity providers have `mdui:DisplayName` + metadata by copying data from `md:OrganizationDisplayName` if required. The copying process also + generates `mdui:Description` elements with the same content. diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index 92fcf779..0460215b 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -125,7 +125,7 @@ odn_to_mdui Ensure that all UKf-registered identity providers have - mdui:DisplayName elements. + mdui:DisplayName and mdui:Description elements. --> @@ -334,6 +334,12 @@ + + + @@ -394,6 +400,12 @@ --> + + + @@ -509,12 +521,6 @@ - - - @@ -632,12 +638,6 @@ - - - @@ -762,6 +762,12 @@ + + + @@ -879,7 +885,7 @@ @@ -1111,6 +1117,12 @@ and pre-production-status MDX relationships. --> + + + From 91d41c06b7bd6a7022ad1285a1c2d482df0edb4e Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 8 Jan 2018 14:19:13 +0000 Subject: [PATCH 27/63] Increase memory allowed for MDA to 1.25GB --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index ad2c509b..0652a36c 100644 --- a/build.xml +++ b/build.xml @@ -334,7 +334,7 @@ be more than some invocations require, but there's no harm in having a higher limit for all of them. --> - + + + From 724330aa2b93b01914969ec40a7a3226b1393d34 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 11 Jan 2018 12:29:32 +0000 Subject: [PATCH 29/63] Add MDUI summary to direct charting statistics --- mdx/uk/statistics-charting.xsl | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/mdx/uk/statistics-charting.xsl b/mdx/uk/statistics-charting.xsl index 0f7a5af8..abebbcef 100644 --- a/mdx/uk/statistics-charting.xsl +++ b/mdx/uk/statistics-charting.xsl @@ -207,6 +207,37 @@ + + + + + + Entities with mdui:UIInfo: + + ( + + ) + + + + + IdPs with mdui:UIInfo: + + ( + + ) + + + + + SPs with mdui:UIInfo: + + ( + + ) + + + From f1fbf442cb4c6d48b53df7bb4ef9dc94495011d1 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 15 Jan 2018 15:10:12 +0000 Subject: [PATCH 30/63] Consolidate ODN-to-MDUI processing Now that this is being done everywhere, we can just do it once, and simplify the way it's done. See ukf/ukf-meta#150. --- mdx/uk/generate.xml | 85 +++++---------------------------------------- 1 file changed, 9 insertions(+), 76 deletions(-) diff --git a/mdx/uk/generate.xml b/mdx/uk/generate.xml index f7ce2f7c..459f39d2 100644 --- a/mdx/uk/generate.xml +++ b/mdx/uk/generate.xml @@ -112,46 +112,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -400,12 +354,6 @@ --> - - - @@ -585,12 +533,6 @@ - - - @@ -768,12 +710,6 @@ - - - @@ -889,12 +825,6 @@ - - - @@ -986,6 +916,15 @@ + + + - - - From d7b746ee4addbb1e9ff397f3095ac6a611d49954 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Thu, 15 Feb 2018 08:32:57 +0000 Subject: [PATCH 31/63] Record Uganda as eduGAIN member, no longer a candidate --- mdx/common-beans.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index 3b7da05a..7e80588c 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -424,6 +424,7 @@ + @@ -444,7 +445,6 @@ - From dee07bd143007a1042c5c5156959c96591fbf573 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Mon, 19 Feb 2018 11:24:19 +0000 Subject: [PATCH 32/63] Correct registrationAuthority string for Belarus --- mdx/common-beans.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index 7e80588c..b7731344 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -299,7 +299,7 @@ - + From 890806936167574ca53fec4ab86a818be96ed094 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Tue, 20 Feb 2018 14:54:01 +0000 Subject: [PATCH 33/63] Correct registrationAuthority string for Belarus (again) --- mdx/common-beans.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index b7731344..786e0159 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -299,7 +299,7 @@ - + From 2bebbc1c8f2fd0457ab4d189812ff95f0b2b7d1e Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Tue, 27 Feb 2018 11:40:44 +0000 Subject: [PATCH 34/63] Add future check whether md:OrganizationDisplayname matches mdui:DisplayName for SPs See ukf/ukf-data#325 --- mdx/_rules/check_future_2.xsl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/mdx/_rules/check_future_2.xsl b/mdx/_rules/check_future_2.xsl index ee51f733..0b697102 100644 --- a/mdx/_rules/check_future_2.xsl +++ b/mdx/_rules/check_future_2.xsl @@ -27,4 +27,27 @@ --> + + + + + + + + mismatched xml:lang='en' DisplayNames: ' + + ' in mdui vs. ' + + ' in ODN + + + + + From 21d93201dc36950f757c90380d8843ec43f14173 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Tue, 27 Feb 2018 11:42:10 +0000 Subject: [PATCH 35/63] Add future check for multiple SLO elements with the same Binding. See ukf/ukf-meta#155 --- mdx/_rules/check_future_1.xsl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/mdx/_rules/check_future_1.xsl b/mdx/_rules/check_future_1.xsl index ed05b114..c6d5d479 100644 --- a/mdx/_rules/check_future_1.xsl +++ b/mdx/_rules/check_future_1.xsl @@ -27,4 +27,31 @@ --> + + + + more than one SingleLogoutService with SAML 2.0 HTTP-POST binding + + + + + + more than one SingleLogoutService with SAML 2.0 HTTP-POST-SimpleSign binding + + + + + + more than one SingleLogoutService with SAML 2.0 HTTP-Redirect binding + + + + From e313b91bd92566fdc5114f68cc0ecb8dfde2fde5 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Tue, 6 Mar 2018 08:43:01 +0000 Subject: [PATCH 36/63] Add future check for algorithm support consistent with new saml2int See ukf/ukf-meta#157 --- mdx/_rules/check_future_4.xsl | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/mdx/_rules/check_future_4.xsl b/mdx/_rules/check_future_4.xsl index 8a7084f8..d7a87d4e 100644 --- a/mdx/_rules/check_future_4.xsl +++ b/mdx/_rules/check_future_4.xsl @@ -17,6 +17,7 @@ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:set="http://exslt.org/sets" + xmlns:alg="urn:oasis:names:tc:SAML:metadata:algsupport" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" @@ -27,4 +28,73 @@ --> + + + + + + + + + + Does not contain a GCM EncryptionMethod specified in new saml2int + + + + + + Does not contain a Key Transport EncryptionMethod specified in new saml2int + + + + + + + + + + + + + + Does not contain a SigningMethod specified in new saml2int + + + + + + Does not contain a DigestMethod specified in new saml2int + + + + + From 0c4b4899a18d9f97aad28cbcc9a7911753402fe8 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Thu, 8 Mar 2018 12:15:42 +0000 Subject: [PATCH 37/63] Remove future check for algorithm support consistent with new saml2int Turns out that future checks are called during metadata import --- mdx/_rules/check_future_4.xsl | 69 ----------------------------------- 1 file changed, 69 deletions(-) diff --git a/mdx/_rules/check_future_4.xsl b/mdx/_rules/check_future_4.xsl index d7a87d4e..ee2b99a7 100644 --- a/mdx/_rules/check_future_4.xsl +++ b/mdx/_rules/check_future_4.xsl @@ -28,73 +28,4 @@ --> - - - - - - - - - - Does not contain a GCM EncryptionMethod specified in new saml2int - - - - - - Does not contain a Key Transport EncryptionMethod specified in new saml2int - - - - - - - - - - - - - - Does not contain a SigningMethod specified in new saml2int - - - - - - Does not contain a DigestMethod specified in new saml2int - - - - - From 1dbd1a0b58fdde046ce8ba2466cffce09f2c8dc6 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Thu, 8 Mar 2018 15:38:24 +0000 Subject: [PATCH 38/63] Re-add future check for algorithm support consistent with new saml2int Check is flagged as warning. See ukf/ukf-meta#157 --- mdx/_rules/check_future_4.xsl | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/mdx/_rules/check_future_4.xsl b/mdx/_rules/check_future_4.xsl index ee2b99a7..ef19cc39 100644 --- a/mdx/_rules/check_future_4.xsl +++ b/mdx/_rules/check_future_4.xsl @@ -28,4 +28,73 @@ --> + + + + + + + + + + Does not contain a GCM EncryptionMethod specified in new saml2int + + + + + + Does not contain a Key Transport EncryptionMethod specified in new saml2int + + + + + + + + + + + + + + Does not contain a SigningMethod specified in new saml2int + + + + + + Does not contain a DigestMethod specified in new saml2int + + + + + From dd671fe5b1159b18aa7358534c83c2c051aa9346 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 11:26:12 +0000 Subject: [PATCH 39/63] Use xsltproc instead of Xalan See ukf/ukf-meta#159. --- charting/mdui.pl | 5 ++--- charting/saml2.pl | 5 ++--- charting/sizes.pl | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/charting/mdui.pl b/charting/mdui.pl index fb2a6bfd..9f0e7791 100755 --- a/charting/mdui.pl +++ b/charting/mdui.pl @@ -4,8 +4,7 @@ # mdui.pl # use warnings; -use lib "../build"; -use Xalan; +use lib '.'; use Months; # Parse command line arguments @@ -29,7 +28,7 @@ foreach $month (@months) { print "Processing $month\n"; - my $command = xalanCall . " -IN cache/$month.xml -XSL statistics_mdui.xsl"; + my $command = "xsltproc statistics_mdui.xsl cache/$month.xml"; # print "command is $command\n"; system($command); # || print "ignoring claimed failure in sub command\n"; # print "Xalan run on $fn\n"; diff --git a/charting/saml2.pl b/charting/saml2.pl index fd790429..0542f210 100755 --- a/charting/saml2.pl +++ b/charting/saml2.pl @@ -6,8 +6,7 @@ # Extracts statistics about SAML 2 adoption from the published metadata. # use warnings; -use lib "../build"; -use Xalan; +use lib "."; use Months; # Parse command line arguments @@ -25,7 +24,7 @@ # ingest files foreach $month (@months) { my $fn = "cache/$month.xml"; - open(TXT, xalanCall . " -IN $fn -XSL saml2.xsl|") || die "could not open input file"; + open(TXT, "xsltproc saml2.xsl $fn|") || die "could not open input file"; $_ = ; chop; # print "$month: $_\n"; diff --git a/charting/sizes.pl b/charting/sizes.pl index 004c6e3f..2fc857b7 100755 --- a/charting/sizes.pl +++ b/charting/sizes.pl @@ -4,9 +4,8 @@ # sizes.pl # use warnings; -use lib "../build"; +use lib "."; use File::stat; -use Xalan; use Months; # Parse command line arguments @@ -47,7 +46,7 @@ # Now generate a reduced version of the archived # file that contains only UK federation registered entities. # - my $command = xalanCall . " -IN $fn -XSL just_ours.xsl -OUT temp.tmp"; + my $command = "xsltproc --output temp.tmp just_ours.xsl $fn"; # print "command is $command\n"; system($command); # || print "ignoring claimed failure in sub command\n"; # print "Xalan run on $fn\n"; From 8db4b4d792cb2e9517e94a1380da2944eda348d5 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 12:19:37 +0000 Subject: [PATCH 40/63] Use xsltproc instead of Xalan See ukf/ukf-meta#159. --- build.xml | 85 +++++++------------------------------- build/extract_embedded.xsl | 5 +-- 2 files changed, 18 insertions(+), 72 deletions(-) diff --git a/build.xml b/build.xml index 0652a36c..d2844e50 100644 --- a/build.xml +++ b/build.xml @@ -264,7 +264,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extracting embedded certificates - + + + + + + Extracting embedded certificates - + + + + + + Checking embedded certificates Note: ignore expiry on eduGAIN entities + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> @@ -49,7 +48,7 @@ -----BEGIN CERTIFICATE----- - + -----END CERTIFICATE----- From 8a297d794265160b33fd38eee6eb371cdd5a47c9 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 13:43:38 +0000 Subject: [PATCH 41/63] Use xsltproc instead of Xalan See ukf/ukf-meta#159. --- utilities/addresses.pl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/utilities/addresses.pl b/utilities/addresses.pl index 1c9772d5..bc605208 100755 --- a/utilities/addresses.pl +++ b/utilities/addresses.pl @@ -1,8 +1,5 @@ #!/usr/bin/perl -use lib "../build"; -use Xalan; - # # Load extra addresses. # @@ -24,7 +21,7 @@ # # UK addresses # -open(XML, xalanCall . " -IN ../mdx/uk/collected.xml -XSL ../build/extract_addresses.xsl|") || die "could not open input file"; +open(XML, "xsltproc ../build/extract_addresses.xsl ../mdx/uk/collected.xml|") || die "could not open input file"; while () { if (/(mailto:)?(.*)<\/EmailAddress>/) { $metadata{$2} = 1; From 7a1f13583f2b5074d40f22ade39111c1a496bd1a Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 13:55:46 +0000 Subject: [PATCH 42/63] Use xsltproc instead of Xalan See ukf/ukf-meta#159. --- charting/scopes.pl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/charting/scopes.pl b/charting/scopes.pl index 3927471b..8a8c6692 100755 --- a/charting/scopes.pl +++ b/charting/scopes.pl @@ -6,8 +6,7 @@ # Extracts statistics about number of scopes from the published metadata. # use warnings; -use lib "../build"; -use Xalan; +use lib "."; use Months; # Parse command line arguments @@ -31,7 +30,7 @@ foreach $month (@months) { my $fn = "cache/$month.xml"; my %scopes; - open(TXT, xalanCall . " -IN $fn -XSL scopes.xsl|") || die "could not open input file"; + open(TXT, "xsltproc scopes.xsl $fn|") || die "could not open input file"; while () { chop; my $scope = $_; From dcddefd5211f39d424de25acb41a2d113be72b70 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 14:00:57 +0000 Subject: [PATCH 43/63] Delete some attic material referencing Xalan See ukf/ukf-meta#159. --- attic/extract_saml2sp.pl | 24 --- attic/extract_saml2sp.xsl | 37 ---- attic/keynames.pl | 49 ------ attic/keynames_inner.pl | 351 -------------------------------------- 4 files changed, 461 deletions(-) delete mode 100755 attic/extract_saml2sp.pl delete mode 100644 attic/extract_saml2sp.xsl delete mode 100755 attic/keynames.pl delete mode 100755 attic/keynames_inner.pl diff --git a/attic/extract_saml2sp.pl b/attic/extract_saml2sp.pl deleted file mode 100755 index 5b7e92be..00000000 --- a/attic/extract_saml2sp.pl +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -w - -use Xalan; - -open(XML, xalanCall . " -IN ../xml/ukfederation-metadata-unsigned.xml -XSL extract_saml2sp.xsl|") || die "could not open input file"; -while () { - my ($id, $result) = split; - $results{$id} = $result; - print $_; -} -close XML; - -open(IDS, "ids.txt") || die "could not open ids file"; -while () { - chop; - $id = $_; - if (defined $results{$id}) { - $result = $results{$id}; - } else { - $result = 'SP?'; - } - print "$result\n"; -} -close IDS; diff --git a/attic/extract_saml2sp.xsl b/attic/extract_saml2sp.xsl deleted file mode 100644 index aa59a0db..00000000 --- a/attic/extract_saml2sp.xsl +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - yes - no - - - - - - - - - diff --git a/attic/keynames.pl b/attic/keynames.pl deleted file mode 100755 index a917025d..00000000 --- a/attic/keynames.pl +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env perl - -# -# keynames.pl -# -# Extracts statistics about KeyName elements from the published metadata. -# -use warnings; -use lib "../build"; -use Xalan; -use Months; - -# Parse command line arguments -use Getopt::Long; -my $allMonths; -GetOptions('all' => \$allMonths); - -# By default, only show results for the most recent month -if (!$allMonths) { - # reduce months table to one element - my $oneMonth = pop @months; - @months = ( $oneMonth ); -} - -# ingest files -foreach $month (@months) { - print "processing $month\n"; - my $fn = "cache/$month.xml"; - my $command = xalanCall . " -IN $fn -XSL ../build/extract_embedded.xsl -OUT temp.tmp"; - # print "command is $command\n"; - system($command); # || print "ignoring claimed failure in sub command\n"; - #print "Xalan run on $fn\n"; - open(TXT, "perl keynames_inner.pl -q ) { - if (/^Total: (\d+)$/) { - $count = $1; - } - print $_ unless $allMonths; - } - close TXT; - push @counts, "$month: $count"; -} - -if ($allMonths) { - print "KeyName count:\n"; - foreach $count (@counts) { - print "$count\n"; - } -} diff --git a/attic/keynames_inner.pl b/attic/keynames_inner.pl deleted file mode 100755 index 3778f942..00000000 --- a/attic/keynames_inner.pl +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/env perl - -use warnings; -use POSIX qw(floor); -use File::Temp qw(tempfile); -use Date::Format; -use Date::Parse; -use Digest::SHA1 qw(sha1 sha1_hex sha1_base64); - -sub error { - my($s) = @_; - push(@olines, ' *** ' . $s . ' ***'); - $printme = 1; -} - -sub warning { - my ($s) = @_; - push(@olines, ' ' . $s); - $printme = 1; -} - -sub comment { - my($s) = @_; - push(@olines, ' (' . $s . ')'); -} - -# -# Process command-line options. -# -while (@ARGV) { - $arg = shift @ARGV; - $quiet = 1 if $arg eq '-q'; -} - -# -# Hash of already-seen blobs. -# -# Each entry in the hash is indexed by the blob itself. Each blob is a concatenated -# sequence of information that uniquely identifies an already checked key. This is -# used to avoid processing the same blob more than once. -# -my %blobs; - -# -# Blob currently being constructed. -# -my $blob; - -# -# The day that follows the end of each bin. -# -# Bin 0, running from 2014-01-01 to 2014-01-31, -# is followed by the start of bin 1 on 2014-02-01. -# -my @binNextDays = ( - "2014-02-01", - "2014-03-01", - "2014-04-01", - "2014-05-01", - "2014-06-01", - "2014-07-01", - "2014-08-01", - "2014-09-01", - "2014-10-01", - "2014-11-01", - "2014-12-01", - "2015-01-01", # 1Q2015 - "2015-04-01", # 2Q2015 - "2015-07-01", # 3Q2015 - "2015-10-01", # 4Q2015 - "2016-01-01", # 2016 - "2017-01-01", # 2017 - "2018-01-01", # 2018... -); - -# -# Names for bins. The index into this array is -# displaced by 1, so that the first element (index 0) -# gives the name for bin -1 ("expired"). -# -my @binNames = ( - "expired", - "Jan 14", - "Feb 14", - "Mar 14", - "Apr 14", - "May 14", - "Jun 14", - "Jul 14", - "Aug 14", - "Sep 14", - "Oct 14", - "Nov 14", - "Dec 14", - "2015Q1", - "2015Q2", - "2015Q3", - "2015Q4", - "2016", - "2017", -); - -my $binEndTimes = (); -for $startDay (@binNextDays) { - #print "startDay is $startDay\n"; - my $endTime = str2time($startDay . "T00:00:00")-1; - push(@binEndTimes, $endTime); - # local $endTimeText = time2str('%Y-%m-%dT%H:%M:%S', $endTime); - # print "end time corresponding to $startDay is $endTime ($endTimeText)\n"; -} - -# -# Proposed evolution deadline. -# -my $deadline = "2015-01-01T00:00:00"; -my $deadlineTime = str2time($deadline); - -# -# Start of the current month, as an approximation of what we want -# to regard as an "expired" certificate. Ideally, this would be -# passed in as a parameter. -# -#my $nowYearMonth = '2012-08-01T00:00:00'; -my $nowYearMonth = time2str('%Y-%m-01T00:00:00', time()); -my $validStart = str2time($nowYearMonth); - -# -# Total size of deduplicated blobs. -# -my $dedupTotal = 0; - -while (<>) { - - # - # Discard blank lines. - # - next if /^\s*$/; - - # - # Handle Entity/KeyName header line. - # - if (/^Entity:/) { - @olines = (); - $printme = 0; - @args = split; - $entity = $args[1]; - $keyname = $args[3]; - - # - # Output header line. - # - $oline = "Entity $entity "; - $hasKeyName = !($keyname eq '(none)'); - if ($hasKeyName) { - $oline .= "has KeyName $keyname"; - } else { - $oline .= "has no KeyName"; - } - push(@olines, $oline); - - # Start the blob like this if you want per-entity deduplication - # $blob = $oline; # start building a new blob - - # Start the blob like this if you want global deduplication - $blob = ""; - - # - # Create a temporary file for this certificate in PEM format. - # - ($fh, $filename) = tempfile(UNLINK => 1); - #print "temp file is: $filename\n"; - - # do not buffer output to the temporary file - select((select($fh), $|=1)[0]); - next; - } - - # - # Put other lines into a temporary file. - # - print $fh $_; - $blob .= '|' . $_; - - # - # If this is the last line of the certificate, actually do - # something with it. - # - if (/END CERTIFICATE/) { - - # - # If the certificate is not associated with a KeyName, - # we ignore it entirely. - # - if (!$hasKeyName) { - # print "ignoring certificate with no KeyName\n"; - close $fh; - next; - } - - # - # Have we seen this blob before? If so, close (and delete) the - # temporary file, and go and look for a new certificate to process. - # - $total_certs++; - if (defined($blobs{$blob})) { - $dedupTotal += (length($blob) - length($_) - 1); - # print "skipping a blob\n"; - close $fh; - next; - } - - # - # Otherwise, remember this blob so that we won't process it again. - # - $blobs{$blob} = 1; - $distinct_certs++; - - # - # Don't close the temporary file yet, because that would cause it - # to be deleted. We've already arranged for buffering to be - # disabled, so the file can simply be passed to other applications - # as input, perhaps multiple times. - # - - # - # Collection of names this certificate contains - # - my %names; - - # - # Use openssl to convert the certificate to text - # - my(@lines, $issuer, $subjectCN, $issuerCN); - $cmd = "openssl x509 -in $filename -noout -text -nameopt RFC2253 -modulus |"; - open(SSL, $cmd) || die "could not open openssl subcommand: $!"; - $expiryBin = -1; - while () { - push @lines, $_; - - if (/^\s*Issuer:\s*(.*)$/) { - $issuer = $1; - if ($issuer =~ /CN=([^,]+)/) { - $issuerCN = $1; - } else { - $issuerCN = $issuer; - } - next; - } - - if (/^\s*Subject:\s*.*?CN=([a-zA-Z0-9\-\.]+).*$/) { - $subjectCN = $1; - $names{lc $subjectCN}++; - # print "subjectCN = $subjectCN\n"; - next; - } - - if (/Not After : (.*)$/) { - $notAfter = $1; - $notAfterTime = str2time($notAfter); - $days = ($notAfterTime-$validStart)/86400.0; - next; - } - } - close SSL; - - # - # Check KeyName if one has been supplied. - # - if ($hasKeyName && !defined($names{lc $keyname})) { - my $nameList = join ", ", sort keys %names; - error("KeyName mismatch: $keyname not in {$nameList}"); - } - - # - # Use openssl to ask whether this matches our trust fabric or not. - # - my $error = ''; - - # - # Close the temporary file, which will also cause - # it to be deleted. - # - close $fh; - - # - # Expiry binning is on the basis of calendar period bins. - # - # Bin -1 is for expired certificates, bin 99 is for those that - # expire on or after 2018-01-01T00:00:00. - # - if ($days < 0) { - $expiryBin = -1; - } else { - $expiryBin = 99; - my $bin = 0; - for $binEndTime (@binEndTimes) { - if ($notAfterTime <= $binEndTime) { - $expiryBin = $bin; - last; - } - $bin++; - } - } - # print "date $notAfter gets bin $expiryBin\n"; - $expiryBinCount{$expiryBin}++; - - # - # Print any interesting things related to this certificate. - # - if ($printme || !$quiet) { - foreach $oline (@olines) { - print $oline, "\n"; - } - print "\n"; - } - } -} - -sub numerically { - $a <=> $b; -} - -if ($total_certs > 1) { - - print "Total certificates: $total_certs\n"; - if ($distinct_certs != $total_certs) { - print "Distinct certificates: $distinct_certs\n"; - } - - print "\nExpiry bins:\n"; - $total = 0; - for $bin (sort numerically keys %expiryBinCount) { - if (defined($expiryBinCount{$bin})) { - $count = $expiryBinCount{$bin}; - } else { - $count = 0; # nothing was put in that bin - } - $total += $count; - if ($bin == 99) { - $binName = ">=2018"; - } else { - $binName = $binNames[$bin+1]; - } - print " $binName: $count\n"; - } - print "Total: $total\n"; - - print "\n"; - - print "Deduplication saves: $dedupTotal\n"; -} From 4f74fc59be34f34889f22bf9e05852d6b45c1b74 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 14:33:28 +0000 Subject: [PATCH 44/63] Use xsltproc instead of Xalan See ukf/ukf-meta#159. --- build/Xalan.pm | 38 ----------------------------------- build/check_entity.pl | 9 ++++----- build/extract_locs.pl | 4 +--- build/extract_locs_edugain.pl | 4 +--- build/extract_locs_noports.pl | 4 +--- build/probe_certs.pl | 11 +++++----- build/probe_nk_certs.pl | 13 ++++++------ build/probe_nk_nocerts.pl | 13 ++++++------ build/probe_nocerts.pl | 11 +++++----- build/probe_openssl.pl | 7 +++---- 10 files changed, 32 insertions(+), 82 deletions(-) delete mode 100755 build/Xalan.pm diff --git a/build/Xalan.pm b/build/Xalan.pm deleted file mode 100755 index be9cbb50..00000000 --- a/build/Xalan.pm +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/perl -w - -# -# Simplified access to the Xalan XSLT processor. -# - -# -# xalanCall -# -# Provides the stem of a "system" call string to access Xalan with the -# required extensions. -# -sub xalanCall -{ - my $xalanRoot = "../tools/xalan"; - - my $res = "java"; - - # Endorsed Xalan and Xerces - $res .= " -Djava.endorsed.dirs=$xalanRoot/endorsed"; - - # Classpath - my $classpath = ''; - while (glob "$xalanRoot/lib/*") { - $classpath .= ':' unless $classpath eq ''; - $classpath .= $_; - } - - $res .= " -cp $classpath"; - - # Class to invoke - $res .= " org.apache.xalan.xslt.Process"; - $res; -} - -#print ">>>" . xalanCall . "<<<\n"; - -1; diff --git a/build/check_entity.pl b/build/check_entity.pl index f891783c..50003122 100755 --- a/build/check_entity.pl +++ b/build/check_entity.pl @@ -1,5 +1,4 @@ #!/usr/bin/perl -w -use Xalan; use File::Temp qw(tempfile); use Date::Parse; use Digest::SHA1 qw(sha1 sha1_hex sha1_base64); @@ -28,16 +27,16 @@ # temporary file $temp = '../xml/embedded.pem'; unlink($temp) if -e $temp; - + # extract embedded certificates - open(EXTRACT, xalanCall . " -IN $fn -OUT $temp -XSL extract_embedded.xsl|") + open(EXTRACT, "xsltproc --output $temp extract_embedded.xsl $fn|") || die "could not open certificate extract process"; while () { print $_; } close EXTRACT; die "no embedded certificates extracted" unless -e $temp; - + # check embedded certificates open(CHECK, "cd ../xml; perl ../build/check_embedded.pl <$temp|") || die "could not open certificate check process"; @@ -47,7 +46,7 @@ print $_; } close CHECK; - + # clean up unlink($temp) if -e $temp; } diff --git a/build/extract_locs.pl b/build/extract_locs.pl index a516194d..97fa27c9 100755 --- a/build/extract_locs.pl +++ b/build/extract_locs.pl @@ -1,8 +1,6 @@ #!/usr/bin/perl -w -use Xalan; - -open(XML, xalanCall . " -IN ../mdx/uk/collected.xml -XSL extract_locs.xsl|") || die "could not open input file"; +open(XML, "xsltproc extract_locs.xsl ../mdx/uk/collected.xml|") || die "could not open input file"; while () { chop; if (/^https:\/\/([^\/:]+(:\d+)?)(\/|$)/) { diff --git a/build/extract_locs_edugain.pl b/build/extract_locs_edugain.pl index daf44512..2774e11e 100755 --- a/build/extract_locs_edugain.pl +++ b/build/extract_locs_edugain.pl @@ -1,8 +1,6 @@ #!/usr/bin/perl -w -use Xalan; - -open(XML, xalanCall . " -IN ../mdx/int_edugain/imported.xml -XSL extract_locs.xsl|") || die "could not open input file"; +open(XML, xalanCall . "xsltproc extract_locs.xsl ../mdx/int_edugain/imported.xml|") || die "could not open input file"; while () { chop; if (/^https:\/\/([^\/:]+(:\d+)?)(\/|$)/) { diff --git a/build/extract_locs_noports.pl b/build/extract_locs_noports.pl index 68eeb366..ed4b925a 100755 --- a/build/extract_locs_noports.pl +++ b/build/extract_locs_noports.pl @@ -1,8 +1,6 @@ #!/usr/bin/perl -w -use Xalan; - -open(XML, xalanCall . " -IN ../mdx/uk/collected.xml -XSL extract_locs.xsl|") || die "could not open input file"; +open(XML, xalanCall . "xsltproc extract_locs.xsl ../mdx/uk/collected.xml|") || die "could not open input file"; while () { chop; if (/^https:\/\/([^\/:]+)(:\d+)?(\/|$)/) { diff --git a/build/probe_certs.pl b/build/probe_certs.pl index 5772c566..58f553fa 100755 --- a/build/probe_certs.pl +++ b/build/probe_certs.pl @@ -1,10 +1,9 @@ #!/usr/bin/perl -w use ExtractCert; -use Xalan; print "Loading endpoint locations...\n"; -open(XML, xalanCall . " -IN ../xml/ukfederation-metadata.xml -XSL extract_cert_locs.xsl|") || die "could not open input file"; +open(XML, "xsltproc extract_cert_locs.xsl ../xml/ukfederation-metadata.xml|") || die "could not open input file"; while () { if (/^http:/) { print "skipping http location: $_"; @@ -37,7 +36,7 @@ # Remove any old copy of the DER file. # unlink $temp_der; - + # # Separate location into host and port. # @@ -58,7 +57,7 @@ $failed{$loc} = 1; next; } - + # # Use openssl to convert the certificate to text # @@ -75,7 +74,7 @@ $subject = $1; } } - + if ($subject eq $issuer) { $issuer = "(self-signed certificate)"; } @@ -101,7 +100,7 @@ print "$n: $issuer\n"; foreach $loc (sort keys %locs) { print " $loc\n"; - } + } } # diff --git a/build/probe_nk_certs.pl b/build/probe_nk_certs.pl index 36554355..337e3e66 100755 --- a/build/probe_nk_certs.pl +++ b/build/probe_nk_certs.pl @@ -3,7 +3,6 @@ use POSIX qw(floor); use Date::Parse; use ExtractCert; -use Xalan; sub error { my($s) = @_; @@ -28,7 +27,7 @@ sub comment { my $longExpiredDays = 30*3; # about three months print "Loading endpoint locations...\n"; -open(XML, xalanCall . " -IN ../xml/ukfederation-metadata.xml -XSL extract_nk_cert_locs.xsl|") || die "could not open input file"; +open(XML, "xsltproc extract_nk_cert_locs.xsl ../xml/ukfederation-metadata.xml|") || die "could not open input file"; while () { my ($entity, $url) = split; if ($url =~ /^https:\/\/([^\/:]+(:\d+)?)\//) { @@ -61,7 +60,7 @@ sub comment { # Remove any old copy of the DER file. # unlink $temp_der; - + # # Separate location into host and port. # @@ -82,7 +81,7 @@ sub comment { $failed{$loc} = 1; next; } - + # # Use openssl to convert the certificate to text # @@ -122,7 +121,7 @@ sub comment { } next; } - + if (/Not After : (.*)$/) { $notAfter = $1; $notAfterTime = str2time($notAfter); @@ -143,7 +142,7 @@ sub comment { } } - + if ($pubSize < 2048) { warning("short public key: $pubSize bits, certificate expires $notAfter"); } @@ -173,7 +172,7 @@ sub comment { print "$n: $issuer\n"; foreach $loc (sort keys %locs) { print " $loc\n"; - } + } } # diff --git a/build/probe_nk_nocerts.pl b/build/probe_nk_nocerts.pl index 808f6ac6..07932fb4 100755 --- a/build/probe_nk_nocerts.pl +++ b/build/probe_nk_nocerts.pl @@ -3,7 +3,6 @@ use POSIX qw(floor); use Date::Parse; use ExtractCert; -use Xalan; sub error { my($s) = @_; @@ -30,7 +29,7 @@ sub comment { my $longExpiredDays = 30*3; # about three months print "Loading endpoint locations...\n"; -open(XML, xalanCall . " -IN ../xml/ukfederation-metadata.xml -XSL extract_nk_nocert_locs.xsl|") || die "could not open input file"; +open(XML, "xsltproc extract_nk_nocert_locs.xsl ../xml/ukfederation-metadata.xml|") || die "could not open input file"; while () { my ($entity, $url) = split; if ($url =~ /^https:\/\/([^\/:]+(:\d+)?)(\/|$)/) { @@ -62,12 +61,12 @@ sub comment { my $entity = $locations{$loc}; print "$count: probing $entity: $loc\n"; $count--; - + # # Remove any old copy of the DER file. # unlink $temp_der; - + # # Separate location into host and port. # @@ -88,7 +87,7 @@ sub comment { $failed{$loc} = 1; next; } - + # # Use openssl to convert the certificate to text # @@ -128,7 +127,7 @@ sub comment { } next; } - + if (/Not After : (.*)$/) { $notAfter = $1; $notAfterTime = str2time($notAfter); @@ -179,7 +178,7 @@ sub comment { print "$n: $issuer\n"; foreach $loc (sort keys %locs) { print " $loc\n"; - } + } } # diff --git a/build/probe_nocerts.pl b/build/probe_nocerts.pl index fbb0771c..cd6f5d8d 100755 --- a/build/probe_nocerts.pl +++ b/build/probe_nocerts.pl @@ -1,12 +1,11 @@ #!/usr/bin/perl -w use ExtractCert; -use Xalan; $known_bad{'census.data-archive.ac.uk:8080'} = 1; # it is really http, not https print "Loading endpoint locations...\n"; -open(XML, xalanCall . " -IN ../xml/ukfederation-metadata.xml -XSL extract_nocert_locs.xsl|") || die "could not open input file"; +open(XML, "xsltproc extract_nocert_locs.xsl ../xml/ukfederation-metadata.xml|") || die "could not open input file"; while () { chop; if (/^http:/) { @@ -39,12 +38,12 @@ foreach $loc (sort keys %locations) { print "$count: probing: $loc\n"; $count--; - + # # Remove any old copy of the DER file. # unlink $temp_der; - + # # Separate location into host and port. # @@ -65,7 +64,7 @@ $failed{$loc} = 1; next; } - + # # Use openssl to convert the certificate to text # @@ -108,7 +107,7 @@ print "$n: $issuer\n"; foreach $loc (sort keys %locs) { print " $loc\n"; - } + } } # diff --git a/build/probe_openssl.pl b/build/probe_openssl.pl index d71e759a..1b2e83cb 100755 --- a/build/probe_openssl.pl +++ b/build/probe_openssl.pl @@ -1,12 +1,11 @@ #!/usr/bin/perl -w use ExtractCert; -use Xalan; $known_bad{'census.data-archive.ac.uk:8080'} = 1; # it is really http, not https print "Loading endpoint locations...\n"; -open(XML, xalanCall . " -IN ../xml/ukfederation-metadata.xml -XSL extract_nocert_locs.xsl|") || die "could not open input file"; +open(XML, "xsltproc extract_nocert_locs.xsl ../xml/ukfederation-metadata.xml|") || die "could not open input file"; while () { chop; if (/^http:/) { @@ -39,12 +38,12 @@ foreach $loc (sort keys %locations) { print "$count: probing: $loc\n"; $count--; - + # # Remove any old copy of the DER file. # unlink $temp_der; - + # # Separate location into host and port. # From bfd4ae272bd6b221f7e6e464c885356ba0bf714e Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 22 Mar 2018 14:40:22 +0000 Subject: [PATCH 45/63] Tidy up some references to Xalan See ukf/ukf-meta#159. --- build/extract_locs_edugain.pl | 2 +- build/extract_locs_noports.pl | 2 +- charting/mdui.pl | 2 +- charting/sizes.pl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/extract_locs_edugain.pl b/build/extract_locs_edugain.pl index 2774e11e..e882d0ca 100755 --- a/build/extract_locs_edugain.pl +++ b/build/extract_locs_edugain.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -open(XML, xalanCall . "xsltproc extract_locs.xsl ../mdx/int_edugain/imported.xml|") || die "could not open input file"; +open(XML, "xsltproc extract_locs.xsl ../mdx/int_edugain/imported.xml|") || die "could not open input file"; while () { chop; if (/^https:\/\/([^\/:]+(:\d+)?)(\/|$)/) { diff --git a/build/extract_locs_noports.pl b/build/extract_locs_noports.pl index ed4b925a..24502aa6 100755 --- a/build/extract_locs_noports.pl +++ b/build/extract_locs_noports.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -w -open(XML, xalanCall . "xsltproc extract_locs.xsl ../mdx/uk/collected.xml|") || die "could not open input file"; +open(XML, "xsltproc extract_locs.xsl ../mdx/uk/collected.xml|") || die "could not open input file"; while () { chop; if (/^https:\/\/([^\/:]+)(:\d+)?(\/|$)/) { diff --git a/charting/mdui.pl b/charting/mdui.pl index 9f0e7791..2651703b 100755 --- a/charting/mdui.pl +++ b/charting/mdui.pl @@ -31,6 +31,6 @@ my $command = "xsltproc statistics_mdui.xsl cache/$month.xml"; # print "command is $command\n"; system($command); # || print "ignoring claimed failure in sub command\n"; - # print "Xalan run on $fn\n"; + # print "xsltproc run on $fn\n"; print "\n"; } diff --git a/charting/sizes.pl b/charting/sizes.pl index 2fc857b7..7f9fa924 100755 --- a/charting/sizes.pl +++ b/charting/sizes.pl @@ -49,7 +49,7 @@ my $command = "xsltproc --output temp.tmp just_ours.xsl $fn"; # print "command is $command\n"; system($command); # || print "ignoring claimed failure in sub command\n"; - # print "Xalan run on $fn\n"; + # print "xsltproc run on $fn\n"; # # Process the reduced version of the archived file. From f9cb04cc4ef57c518bac6fb67cab182258abdfba Mon Sep 17 00:00:00 2001 From: Ian Young Date: Tue, 27 Mar 2018 11:50:48 +0100 Subject: [PATCH 46/63] Upgrade to ukf-mda v0.9.7 Relaxes the definition of a clash between identity provider display names to ignore md:OrganizationDisplayName for any IdP that has mdui:DisplayName. See ukf/ukf-meta#150. --- .../{ukf-mda-0.9.6.jar => ukf-mda-0.9.7.jar} | Bin 59056 -> 59089 bytes 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/ukf-mda/{ukf-mda-0.9.6.jar => ukf-mda-0.9.7.jar} (72%) diff --git a/tools/ukf-mda/ukf-mda-0.9.6.jar b/tools/ukf-mda/ukf-mda-0.9.7.jar similarity index 72% rename from tools/ukf-mda/ukf-mda-0.9.6.jar rename to tools/ukf-mda/ukf-mda-0.9.7.jar index 1a6bc23d8c834bbdcb66883cfbb3e9bc3bc54e85..f0df7fd5fe10083f9fbb9d58fb040e61ca3c67ca 100644 GIT binary patch delta 7972 zcmaKR1yq!6(DqW&C`d?y(jC$wpoCI_fONNXNXrT+-H()XgEUJB(nxnN-5}C!5Z}V? z?QEaWF}K?zwDfk76A3j@ec;X)4*6A)R2`AD5rg;dZVJCWwO320Hvn__Z1sJ6^}s-MeuzK@`Gk?vxN2`J9H0Hm*`S7)SSopQAV7S<@5`hpiQmDP5g*bB+533%LWV0%;r4}IZtCbp zuJe)Q?C;ykXAd4{_K9i!EG&L>w{3mT9a}$e;eHava%$zJ(Y?!z^SGnsxEQE<#!r?8 zv&BvPLRI&awnk~D4yW2PTyV_y#3?Vii3|2nyMX;rBH(;|*ocp_)FHc>&E-wd-1Ac`xh|uxpnE@nSTSEU zHxn7(23grMl1AWJAbD1lMlexS=|fF|GCDG15wUJ&BGTWNq+r{-xi0g@2`i}wsAAAGT2hB*aHSgFSeoXt#c_2i|H5a zo+o&=q~D1injDf!6pHD0(gjbRZ|*)jTIVILZbAvEt4KVoKiBKtulKTratbyi3fp9=fghdwo~jM!8H*%`3fF^TkYlj z_#aAhAI7R>&rnUcsx-v);QUdPjtVo^X>1tx#VxYxzgx7lB`Hvqa$7-)Nv9BB^YIwP zQ$-)y-?oOqx@+NrZ9Dj!i93C@nOQ6v6R*8i2WwUDCsQk^jteBW9ghzxMHdKb9xu=+ zNb#{(%eoor*7^=6%Yu~#<-e$)-%8>(e$0UDliY0%srXQyUaAc?8|uxK>^dzEGMo^= zka~MsI-fl7OFB=(U1q$?lmInaI#+U7Wx;9Bz` z)s9Czuio_cb=^sP+$Ei&7jo?g`{wCt=b@F=nQ` z>CeBn#(SGu6<-LOcX>%1B!!R11mx@oo64L<;1C_4Clq4&wn3D#u=&G;(P!qK&<@!A z8c%pQU}t*roxkuq#5+IFTW{24sH2XE?WVtZf*o(XhbylFvJ6 zhYi>(_R9cz*S<;NG$um-%`3jz zAD`4`)AyWI@;3_!a8w!mH^g;y2NVtXi9XKRs5Iv<|5{h@mrd;?(qa7AA`ee4LzppPNbtqbH2jCFvIl zvefatCJhwj5L+iTTP#+sdTHZ4@VP5qV9hZu5&DBrSB1KFrz~pGD?ie)+Wph+bbmhd zi%z9Mx&UPuGff4!zc4$`{>ZOKbI(rDc?eeP` zX(I?Nq>q*G-0=;MXPA-k?fB2?FNz*%f0mN#$#cs3AX~ZRq&@mFmaWV*U&mybWG_Vi z!aT!NuF~M4CNwt0G=V+tS%|^hQ6e-}&a{R-t_w^1)enmpFn__ZctPPJrIlP_#k5<5 z^Bz{AvAnjhX$^hcbaW&uDv4smWD))N3lAZ7rdr$LY)9;>?|g&hQ?ab3>~dIm=c9^ATe!`+A3z<8kgL@BryY}Z z2D}V=h_RTpv$gGqCd=Qkiw@h!l~_YoZ`F;&ZkOu}W~j^c(B@i%?yhKg^i>WF$`jRb zi|HHilxxP!S}Y5=VKfHoXQt;)H^(LtPQ=M=+4M)oV&d;)yFRnie zUP&PLprUs3nom}a3a`wJba0&0Wnf@HV*om8avwCK9m^`mPN)I*)pon@=p3r3@xCrYmM`(>LI-TM8+vqtg(oA%3`2 zmRE2{F=uaEdmy@=?vaw6VjZc#op}9m#VONw+v)&xm7Zk z7{3;l`L!3t)hiN&s)_BG?vZROTHe$3y-Y%O^o=6gPkA)f0S03+fw+B{(BQW$_WHVl zs#&^#zVl&DVytJ~5=Vp8%$&|@30m~17)eqYw?K!bIi;a_i~93JEsH=lBe2f=KDCbhQq!z)g!)+GB9jGIFnx{9)TMrrG@4O+qpB@oNY4Gq0ASLfbGiX%G> z1Z^5`ZS4!hrFJ>a?cUq}m`BrNA0??&^o~_idDmbqos>bQtIwa4_(PlT(uQpnkLcm> z7&)W*u@8RXy`tSR*1{^kZNZ1$yeVjFa_M0(XT&}x7~$Ce11M^pRIpgU2&@hR zKbd&teli3w-z<2VHoj#8VVsaclpINY(I&8@}PBAR5X^O7hP(RQQu4)pS=24YZdOX*)fD3(+r2F> ztO;jD1H8=L$Av2vDQU}sYt%AZdTc9RJ_-5;Yv~IpI*TDTd(e#+{Ex(6;Y$BjvoP8m zw*OP+3#HFo(iU!Ik(arw2=^xVF z?2$>Zb~?8A7g`2UiP87ymb%*AmQiCdqKT9Jv}3V$+GHtHze#1eI9N|Q=nzyxziB}! zIJVq=<@pzAx(mWe8?WLJJD0(xz~#}oQ98gxO09IfsNDA za8=k;EAL`k5xmkr=knycY)^0z4vN`Q$E~Oo3mv0ew%CquB5NBTkKu zF7vPQ2Z}XOA7I4bdie*e9XwrsUO3+>*)Fgy$d98+VIIj!P8ur_HeIkGXteR2EPb%c zgsC56jxGjc?Tg$4!8teN397cGFWH}~DLdAnZ$>W!i^cqNr@G5 z-z^)drWQF~N}z+Js#ES+Y8^q2z6=(bdG;uY1$2G9(J-Xe!us&=H5UL%bEE20@_AXL}{6V&7xHz@x zOYI1feX10Ud~DUX5t*maECpbPn)l2LZ;$Gw9BFrWpDR4|5_u8pUY}amO|ioez%%>D z%6VQt{g2+6W!O~eSl-*T=v#KaZ?JmUydp7MTFO+uG`9rEbDSNjjGmN4@Klzf)V}c! zIH+ce5s-~}hE~o+oALd08rj`fN($Q{Dy?}-_Ss~GKSz_;Hs}- z6$J=?J}xrWf5j2tTQ~D{bp+V&7KIBuJyNLnSH%p^9u;I_XJD|01&kiiamW(4R1Bxe`Ss`e+U))NnNhCM!`H_uW*&)C{q`x3)QzN;U7ZWM5H z47uA5?A?;{%ev6=Srp7%%oVFA_6qjRC7U-_7_{4xfA4m7E;b>RX}+*hEj z4=vS*dy>L(paW7(aU&fQY$p@=gu6^Ox`}%%?0Gqw7h0N8hVJFRZhSX0okIx{`_7JW zg;?!^>YWY|53WKmb7$H64F!DK`{ke{vWMY(kLU&bOsaCu(>u8Urv*aK|8F1aU?fes~QOk?h$9zby!2F)bi}X}*W=|4L&Ujtp zzF;;|uImS^zy&hAm+sG0BT1CI1Mhy3PF)gICr?+4vz=h-04vKb+lQ(6WnWCG-3hhO zKr<$OZ0l0=S;06J>0cK)g%(3^NVK%$3!p*BP5`kCU?A z6`0)$4c?_!cK*YuI={`^R8ifS3Q5Wd9nn;F;aG|bwH=6j0{NIg?xg6P9O4~|X`I|F zH)YhXMTccTqp|U^zm)d=Al=Mwf&G)SZi@c6UVM~XkJ~fgVbwc1r@VJ63pv9+biOU- zW_~%MC>EUAdOobA%8_1gTRTr`FN>LqA>^P_YhPP=Ci*SDZ7`-Wg=5Ws_h~a<58k*} z>xqEcZ_U$|A+_5*MW;fze9*ON^tkh>P1V3WjkNXB)YN2L^HWn3Whpl|Sq|~94z77e z6eM#$p8pn;0BbL~J%;WKxd#X-GThF1u;FZZ;=ahzJ#yc0W*hqY+>iL6)}6v5lEW&N zu>9?}YR-<;2)+AhT}K#->8(db49r6t-f4F1QfAaAgZ?J*9VtRSd97xJ8w)Ip;T6>n zNTh_MKI0@|yb?25jm+n3=WNUMGbeJM;ns0=`(b#`1OOk7?-WZI9mfZV+(NH<-{G;E zy}KylM$&tvB_Jk~Y&J~MQO3B{iKv|y3^ugMPR;3i{lzk5KbBZB>m=_JMgpq<(Vxq1 zcabFd#{=M;By-a<$}l4w1v&=ppv*wZyu{3%ui}1Pn_&mEi1T?sQiWUPGBaM#&cylC-gkuL&tH-mKGjE4|liH zPy(PkJbv0e-c?p{^;jwYCHdjyZqe|n_(r@}!MP=vcQ=juFe^kM42i10{@z?f=+`Yy zbUUuohNci62k>(X4VnUObA6lA$7+#CWxOQXXm3;WdT>j^N_9jW9qB`3jt zkUu{JgOK54S;)vs74ddtHG6vE7?T`&hPZdxBhF4L1n`3S=~SJr9c+_#fqj+akdO&c z{@Yd%d;j$hCJ;HyfO(b7b%`Bl92SD_h-brOB%?6Mbv^w*|LaOO`v{r9G2CY7Xbx-S zP5Zz6gnu9IfVL&bkO0~kV!&e+hvt8uMDE=H%3lG=fTVle(Y>(prqS4p9QK&O}>5dRIQ zZaSEg}3(S0diu7r6B~&Eg*VkXMqe^h7G2p02me#|L({wk|9Gm zu62Hkgzzbn2-7k1Uh75{*{*}A-5T;!gtb-h4hTehBS<7a3`hp#jT6D0n_=D0E_|&M zr$Ys(pqK#a1cI1if(*G+^oC7;0zM1ET7*8KAb~)wu&>yS0ICu<9BL;Rt~08jXi`*$ z^-DM@2*i5B;oFmc9LV8Wi9*ScZRP*!U7=LhB!&`8gzT_pU5yOa4HEAcf59VAnrpCV zrA%uk3@i^DZ@wE~Ocex}5KyGS1Y{=>9j-M=hJ0K7+7>y<3eThwro+@m;0XY`DRkIz zoaj1$b(YA>t88juBl+k?fOfrq9H`(#QB!0{x!h1gY_|~s#sVf+NE!ZHBYI&+ zWiwdj#kl`_U8`?KxL^WLmf!=>k3yom4C6nA@!wo4qC5YB`SXc^trZ;j&FO4~3~34= zS*4=6+U@?yAN1hw!_^*z-UEpD&|mFQaKGSHGUR7hI!>0WbsL`V)fMdDeVyko#nn0- gbp>Y!*w*e|$NG0K7PryLoT==t(35W(kZAk5+dCq zB}z$t3(N0)<^6wL*IvwX=FFKhvCr&%PhS`An=V`mT@7435)g<81d8?1*NCIw!aMyh z;cv)(LGd%xr%u0IQPSx9#a1R{%1^HiFC37r1|iXI@}0XbAP^`7^Z8dH2BUxh{`tej zlT{~wf0UjGbrwh}}m z6mQ^A|95l(z_d9V`ba5|7%LyFNrr8Lj@F4dYkb&%9f!6dDX=<5j5dYVoz;Z!oz|eW z4L_VArhZodZ9`&!!h#TObl3k(Yrq^hD>++Dk^CPMsu&a8=!9@fQml#HIN>w8j%zSJ z7VGhf#KV?M{pPVefIpEJn3^C#`#t^+KCJ^fnt0KTxJ!iCr(#kAII+L!;QgZ>hgGbSwnD9|^qeVDX+Z{&g z;H%L*y9pr;{eNCj?fHCf{!)GLR#+jsS1f98L{vVaVQAVI7oIJXK{1Ty*EWi&=68eW7T^IaM~cal6f;lQkFGq0 zlg!8jZfB4mXb`1sWQDAUZlhr*4ucmI6`+FZxM&(z{r$C!w2wrXcOLi zoBoiQ5T3UX=}=QuXWc7}i~%YQj|x9em(te7OkP2hD!v@C{PoZ4Dbk zOi17G$hW+%!@^j-r0Tc+({d8ka+_d#bBD-DKQ$+_Oa#!n<^9TfbS-MzHeOAp16NDC zS-YnD%4N4I?Mreic0$A22-3=}T-R$zCQk%wSB{Gxx3m+y2G;CV>`>|)yA6|535xTb9YJ}j?9#dR4ixGFrIa4UOO;SPb{x-9Y)k>OJ83xQLAv_cB~n!pm%Y1tW$NK zU$`7-*72eD4k^C3EvI3ZZ+m89ZhXm$7xT$HT(A=7RyCeL{cYY?B$bu^WnNy+vdE9o zx1R0GFc8(jq}BU#*#%gbGYbpy?j;kI7N{Fiy}wIL0{`K-w!87rxzn3%`AK86y*}Tb z(unTYI)zGyiF}8N`}%$NMz;iMeOIAwhL=_Yl_cmz^HNKGk#;YHrI18A3;~hJ?>;pD? zm&KJ0%;8SR`L~)wQ8i-mq1DBu-6i)Ca-FS3-eoE;3i-(nXXZ%s))16-Vwa6xm4_z& z*0nhpj4^3nMY%{Szt!w8MKZh-gF6KkF}`t=&sRi!QSa->nipyHDo$cGyYR*opX?j= zZSE-K$IbNe*??q^9NTb-YLcez*3DWy?=jY$s1*1IDKoUCVy~s3E0J4CtHBS%^4F?@ zcEMyerVg8NhuTh&Z;4j;@+nJN&^Vv5wVr&_h*Z_;hY_2p_|gF(<_6~K%iR3&IUe$| zPPVb5krT}u&J1_5(XWFfn9CKeBuXf;w_p8j!wG`KM{y2DF&W^#Q z!4K5%t2U7w8sx@psP^Z#B!j{Q8Nvd!KdfF^ZxfxPX|miZs52^otT;bQHgMl-RT?%p z=A5;>l}5d&2$Q(Hnk0?jbk{OnuzJ_kbJ5P^jTnmGm&xq6)76FOk=F9;pyKq^EyCY~ zt`1T_PuuDP#L#}FiUd>I9a71_#Gw@1u%xOwIBjC|BHGvs!OHyU8_epfwB5S+#wBLz zv7gm@Y|5~de(q$XRM@DRi+sn5clq^qy)QZ^vs2#VM&L8q`JuXU^Kt_QAntkkUAI^5 zwh}l5v?4$9UvO{LDLb-IO_9qD?-OXvD@y9ntTG)UN`g(a=9zMI<(cvsrg~K9->fJJufFr*(zH;nO!H!)KzhVo^Gs7}k!HRf z1yfC6HfV~P_fz&xw{>srmdNlKi?d6zg_{^oJ&XIjRi5bD&M7P&9wa;!%wxo0*==Mi9=(c(?-?)D=pPW)3a?8q5-f>>G;qKA` z>w3REtPS0rlJ=>bBDGw{?dpa$Yje-^;?k@-LrS@YR&}e*vM)Mo(n>Xh@9?VS3_SU# z8KxF+@>3Gm=k3*cPP&&jPru z-DLBgmIH* zwrr&OO0zsu6=+OT&b+J^GEFQg23&3J7V<_NB?fix1Q_EI}3nCqT7!Cd(k+50#W zMhY_~pwR@*j>X$aBp0+4AKdcSnYou&yOub!Q~7eDd73{KX|lgon>e#omK6n0|E83N zn%*_x!!r-~l$L^&;?@Rfig^cOY1 zR%n?a{#vmU1>MqAXZu*c`Y=uVCzd&&ZB2~-MNGIH4@zr{$W^{R}ej`X)^v!eJ`xRz7hT?_Je z$Z!SDTn6dt`SxR+2v!kD`KB3{e@AlzzCk3694Z+mtdSu9iJzaHCF6~^_K)}tE%xO!XBxP z(&iNR`4LFyG*0@`hqOQo;19rU5prJi?F3oi;pSMgg4>h`FI##FE(D%^NQ`wWtXZ#Q z^KRxUmnf^yg;!gWl$}z{ysRh=fp+d&QDK4C_oas4T_fnpT-&bP=GPy`c}$YVofVcw zLKqcB=OybsrtP;T*S&88=y9SX6-i7BwF9?=QX0aytzn z6JBvgTD`(LVcYI=U<$ZCBuKI!1#_h>dtq_A3ibl9J&gZo*(qj6<0nQH{4p?zSX_9Y z!-;$@t292=$zomLF8sYEu4D=KEvAoBi|jkB#?j;?GAv@nS=EL0UmRX5c3Pn2-f&WF z=*;RjJ$^4XV?mwLrp_iGqFN-WFB4-Bn$k4I{@JPN&?x_>vFRMyW8ZGNe3)FJ=f zm%;T$z5_w+Su_8q`;@ceD1(RsA7(QYzH=m93vs%Q_?DMn!ey{ie0eTglYd`-EUi#+ zuiV^SWjD274@u_(oUgy%8m&9XJ2Hy=)@Ivbj+?RU4h)MrOsx`3Y>*`B@!$XO02Prm z-1$rQla5QinvwMu{6YHQVcNpplHic1`Q+r#5u>C_y3#XnF^Nm?TbF`MI=MUjy6e{C z{t6{|tJnGkouU`O^X1iPQ6Uv1$x{pkIi*D=_ZBCt3iKA*vgjM61mXm)B19frwbjMh z5BL`@I=xgvLnnxUfh$skGuq-3XoR#qty4N? zk`bRdcw+es->z-ulG~5rwt_4?^$q_RO8c@u9zooqPlOmqOkc866GMyQ>}3P|==_uB zSz1NJ+FBn!eDb{K@xw&j7{a=U=NYt;v%^IA3r6BIr8Hbm`eH5G-G34#Zpn2hYwW(9 z6|7{n8~k=DVd)$E$SQ%%!(PU_w^S{VMNF6MNeM&VcZ3mpvrmlL6*J=X0iT!wl;Wae zQ8eT0z)@~DhcT7a%bv4%D5qxw+V^%2{rhpZTSMcf#J7JLndOu;;!yI>d47+2!ue9o zr@fhpYua&hSGL5iH5h5YO#?&hJ9+Hm=~Ii*?6SMm-SXLiUt+V`nrIdjgmB(UQ>P(T z`N2gF{i@?AO$#l&8DX`x$2j3kmqo)f7Owh$cvx^sJH5esW~_sO|MQgz=f=xReL7+@ zs3yr^`kIaFuyA`%0r{Two-1}((c5f$pznW*>sb&L+|U4Apyh@Yta>Dm?g zb>+`7tB8}*0lZVAgMB`*uOq}neMk1f{$Y{j=+CQKN9J07OS~UgUw+wjCD3?m8Zyc8 zfDJjPe}FP<60h3%Z4)v~__45Y+T4q`_d%xS4z5ad{sw&C)`>Fd)uCe9!Z>)Ad5CdW z8JA7`XYchf8_Q;aVE874Gq+27NO9eLhAuk&a@?a3g*?W2@63(hU1*O)bH5p{L~LjG zZv_D%`MGI1lQmE2>EH1}t*^bj)9yI3)$1Iv{fr8Byk$Ydj}&}Li8-^U?-Sp+o$XHZ zEPh%nz9Rpvfl}rlgs`q9*MgC7j*PaTot*(sJSL zb$_`0vr;yJ#$()*{D5HFx2G%=AkY{aHa|cMA|fIJokY-ROUS`lgvy^7h>h;i1sMg{ zC=_kU>O+8yRljoQo<*%8e7$G227)nXr3GOvY%O5w$BVWQlR4AuXzIhZ2TlTP_#6dr zFh`AE{J4Wd@|TA@Sqx|KvU_pn8Q;BF0+6jG2P|i)(6(<;*f9cSx9iH>0-DvVUK7!8sIM`w)TfSnsp|MaVZH%$J`Qvi z2%dSk^jix-j<~FkldT;2kXPi-IOFu|jPWJv=3DjA5|@(((C# zg@7otz4*aq{;<_gk9bw2rBDuoUgseH8%-WKT$3(NaJY+NVcjH$FD#jwep&w`R0T!) z=<@}UY)HG&>@D;?)5n2zFU{@OGa!l7F!Ak2JwJn8x*ZBg2a0&6Mv1Fb5*rBF4WDQ# zU$7#v61*1(z4`R1ASj<8#+qE`Qx|(m@g_r*t$&%6f(5>r35&7*9Bp*YXJS0v@G-Hf zNALn4RiRn(`VSB1^X>l7Rf~JdRu4s)^ol>Td}%Cq+whi`%PYFDAeBn>b?A>3B0Vvs z(#OMPW!!2=(hrTl&1#r_)$=5+MJs!E1gk+w+DYo8gP7MgZsKcLFPd<^&&A32dqVPb z3L>l@pmygugWl(--X1aXA3RGWl?sK&OY{)%?1Z*yNIrqaVMQT3W8WK+Ho@Sr6_df= ztG+CgoXp-g=6|@qgBMIObzXZZwchKA5@`Kd|M_Xe3PEmr@LbzM>g6Nx?89~VRAFY& z)^hxFC@WOk1etq0wXb`zJUw^7J3w~QZv>fJFSa=R=~j+~NQbzT`J3V!FP6L4Zuc)J z!%I_=gc)1*-&5T=!$|4F>@EOaQkT`#WSV$v9IK-GKXcWD&mWxmXT&PRG1b=*;I z$4`EIlgHJ(dw7^WFK(OOEp3}m)iAfTO~xm#k@_mdTYH#q6RpX(OlICs?>)?^2f}Sq z&-V!@rw+L^J=75SZqabTtKKG>QED(~DhZw!Dq5EjQegYQQSj!PcZ^yb(sxgfnPn|G zJj;uC_5PQ`?nhAd-J2gHm;0Z5>6%}kjy5JU`?I`cd6?7rp#hvsG&Fd&43 zjNIya91EHxC*|L-44daG-TVNSi#R-3ageGJ(V;g8i^y*Uzh&}^(C_h_E=J`XUw8}W zK`cIAHGkokGHdgTQ#xKd*)D^jBuiF^rfnQiJfz^jQJU8Nl5o1*PK{&qcJRKJ>Ctx{ zFj6yiidI@v#4euZ#Twz>kiO0KJxW*A@PL(6rl-;_ZAgj|nl;rR8GYW*eEPOit@pMl ziv!DVQ3Hs*XwG}naR7P?O(}<=Jq3JU7fTf^aiV1wNx}lgJ zz5Gi?@RrK<8HAQW93Q38MTHBVIB|f1 zE@jY5y)WJF=32Cg;rGQu$PZu=5fjS_@=WfIiZ`7~Uti~ddO^#MOVi)Ae46_WcljIu zYn$xjZR@>hRh}pn^);mS`j2{2@swKmF8E>Xh#AvZ5pvE0wlu6&;R~~D&(wBeBa$Al z?(lHk5qln7#8CdL9m%mzJCBfhjVr(xWwQn{@G$SLRyH!aq$xs4nWSf>G(znyL-||# z)2mumegh}#qvJY*YGz&*z`a5N?z+GtZin(Idv&F;rHY|tKh87xaDIw>VS>S5@6wtG zF*)f?iG`Iyxgs4pn;R>gA7F|Z`NLi<&a;J6;$i!f!E56BECUoTU);Nr%kzu`tvF(4 zJDw4ZuE4bJsuAXpsO{%8!q4dE`S7eY! z!F>wSZ~}2g4y#Kuv#m$+RtEOS^i0%gFrxO zKQHl#nbUkbFx7t@o1JC(0$~{ZUvmB5)~D%i?JtmP+t@mHFMCY#{e1mj>LA*G9;iU8 zicC0wXE;5OHc!U(-&8l_IieOY_2n|w2{P?6DE7gBH0)7rcaOwb$0a5n<%JH6) zJ2+|25BwM)!)oqfG?l;@3<8J_GGH-{K}Dt zeEQN)d zIbr}ahA4kZlB>Agl8qs05`sVy=SX<$n69}n7ZN8I7g)uhT7%U@47muScv8u|Q z1iEpqvp?n-vi7O=SU1z7)KDG5tr{D#lL?_E1x3^I-QcGhOeEf z;`A!s&Be?r8%Fv3Uaa;%CB7QwI3)_8D~G5s@0%co|9Y$rJ|&6{k^*LlEWq>Wvq{OE zhJd9aPV0IzLQiTF-Bb)vzevOHL5|KHnI@oJQ?VzmClmrIXeuog#5n? z#+h~cJ~?P&|7XFvaT&~JF<r6Ee5{{c+8%0A7QXxtr$!k=$)lG z?TnCl49^+kj2h$Y{I~u4M+}i05NW&skk6B0!x@%&2u>v+HP4EDJb5k8eg@bVcutN8 yELMo2a06@$!UBI!?@0{w_qlrY+_+pZd_}gCL+$TF@cKDU8USC=B=GJ(0skMRYD*jd From fee4cc5d5d59d75df9277225481c559b0aadc547 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 29 Mar 2018 12:00:28 +0100 Subject: [PATCH 47/63] Restore direct checking of an Austrian IdP Resolves ukf/ukf-data#20. --- mdx/at_aconet/verbs.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mdx/at_aconet/verbs.xml b/mdx/at_aconet/verbs.xml index 54399699..64da4a80 100644 --- a/mdx/at_aconet/verbs.xml +++ b/mdx/at_aconet/verbs.xml @@ -88,14 +88,13 @@ - https://zididp.uni-graz.at/idp/shibboleth From fca94f270faab01c00f5dc21ebb2766e24885c64 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 30 Apr 2018 17:06:47 +0100 Subject: [PATCH 48/63] Ignore unknown namespaces on import Resolves ukf/ukf-meta#154. --- mdx/uk/verbs.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/mdx/uk/verbs.xml b/mdx/uk/verbs.xml index 6d066051..6c6c9136 100644 --- a/mdx/uk/verbs.xml +++ b/mdx/uk/verbs.xml @@ -259,6 +259,32 @@ + + + + + + + + + + + + + + + + + + + + + + From a758e63a0ff1fa385c5001286891b8c80b38cf07 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Sat, 23 Jun 2018 14:10:46 +0100 Subject: [PATCH 49/63] Update for new Wugen filenames --- utilities/stats-generate.sh | 4 ++-- utilities/stats-sync.sh | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/utilities/stats-generate.sh b/utilities/stats-generate.sh index 2debef68..de8365d3 100755 --- a/utilities/stats-generate.sh +++ b/utilities/stats-generate.sh @@ -635,10 +635,10 @@ cdswayfcount=$(grep $apachesearchterm $logslocation/cds/shib-cds1/ssl_access_log # ===== # Total WAYFless URLs generated -wugencount=$(grep $date $logslocation/wugen/urlgenerator-audit.* | wc -l | awk '{ printf ("%'"'"'d\n", $0) }') +wugencount=$(grep $date $logslocation/wugen/urlgenerator-audit.* $logslocation/wugen/wayfless-url-generator-audit.* | wc -l | awk '{ printf ("%'"'"'d\n", $0) }') # New subscribers to WAYFless URLs -wugennewsubs=$(grep $date $logslocation/wugen/urlgenerator-process.* | grep "Subscribing user and service provider" | wc -l | awk '{ printf ("%'"'"'d\n", $0) }') +wugennewsubs=$(grep $date $logslocation/wugen/urlgenerator-process.* $logslocation/wugen/wayfless-url-generator-process.* | grep "Subscribing user and service provider" | wc -l | awk '{ printf ("%'"'"'d\n", $0) }') # ===== diff --git a/utilities/stats-sync.sh b/utilities/stats-sync.sh index f2fdba77..1bf2b579 100755 --- a/utilities/stats-sync.sh +++ b/utilities/stats-sync.sh @@ -28,6 +28,7 @@ rsync -at --exclude modsec* stats@www-we-01:/var/log/httpd/* $logslocation/www/w # Logs from Wugen rsync -at --exclude modsec* stats@wugen:/var/log/httpd/* $logslocation/wugen/ rsync -at stats@wugen:/opt/wugen/logs/urlgenerator-* $logslocation/wugen/ +rsync -at stats@wugen:/opt/wugen/logs/wayfless-* $logslocation/wugen/ # Logs from Test IdP rsync -at --exclude modsec* stats@test-idp:/var/log/httpd/* $logslocation/test-idp/ From 0e8f0aca76a0f1fd999ef3899cde61fd40d13567 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Fri, 29 Jun 2018 08:49:52 +0100 Subject: [PATCH 50/63] Enable check_future_5 to check validity of errorURL See ukf/ukf-meta#164 --- mdx/_rules/check_future_5.xsl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mdx/_rules/check_future_5.xsl b/mdx/_rules/check_future_5.xsl index 8ebfc25d..ca6bcd72 100644 --- a/mdx/_rules/check_future_5.xsl +++ b/mdx/_rules/check_future_5.xsl @@ -13,6 +13,7 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" + xmlns:mdxURL="xalan://uk.ac.sdss.xalan.md.URLchecker" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:idpdisc="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" xmlns:set="http://exslt.org/sets" @@ -23,4 +24,16 @@ --> + + + + + ' + + ' is not a valid URL: + + + + + From f55cd7f0be1650784062583e0dd34e7a55e95c05 Mon Sep 17 00:00:00 2001 From: Alex Stuart Date: Fri, 6 Jul 2018 12:14:46 +0100 Subject: [PATCH 51/63] Add warning to check_future_9 for SPs that WantAssertionsSigned See ukf/ukf-meta#165 --- mdx/_rules/check_future_9.xsl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mdx/_rules/check_future_9.xsl b/mdx/_rules/check_future_9.xsl index 54911d3d..546f4275 100644 --- a/mdx/_rules/check_future_9.xsl +++ b/mdx/_rules/check_future_9.xsl @@ -6,7 +6,8 @@ Checking ruleset containing rules that we don't currently implement, but which we may implement in the future. - Author: Ian A. Young + This is to warn if an SP suggests that it wants signed assertions. + Typically, it is the response that should be signed. --> + + + SP sets WantAssertionsSigned, although typically you would want Responses signed not Assertions + + + From 549acc5839d6a63ef0edc56f72a3156ac70acfed Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Thu, 16 Aug 2018 15:06:11 +0100 Subject: [PATCH 52/63] Add eduroam.cz eduroamUID SAML2 attribute to whitelist --- mdx/_rules/check_reqattr.xsl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mdx/_rules/check_reqattr.xsl b/mdx/_rules/check_reqattr.xsl index 455d35e8..3bdb565d 100644 --- a/mdx/_rules/check_reqattr.xsl +++ b/mdx/_rules/check_reqattr.xsl @@ -28,6 +28,10 @@ http://www.terena.org/registry/terena.org/attribute-def/ http://www.terena.org/registry/terena.org/schac/ Assuming encoding rules equivalent to MACEAttr. + + * eduroam.cz + Currently only a single attribute, documented at: + https://www.eduroam.cz/attributes/eduroamUID Author: Ian A. Young @@ -482,6 +486,12 @@ + + + + @@ -1289,6 +1296,22 @@ + Verifying metadata held at ${cdi-master.name} + + + + + + + + Verifying metadata held at ${md.dist.host-ne-01.name} @@ -1360,10 +1383,14 @@ Verify a few select mdq files held on the master distribution site. --> - Verifying MDQ held at ${mdq.dist.name} - - - + Verifying MDQ held at ${cdi-master.name}${cdi-master.mdq.path.name} + + + + Verifying MDQ held at ${mdq.dist.name} + + + @@ -2021,6 +2048,12 @@ Push metadata files for the UK Federation to the MD dist servers --> Pushing UK Federation metadata files to MD dist. + -> CDI-master + + + + + -> MD-NE-01 @@ -2052,6 +2085,12 @@ Push mdq cache tar to the MD dist servers --> Pushing UK Federation mdq cache to MD dist. + -> CDI-master + + + + + -> MD-NE-01 diff --git a/preprod.properties b/preprod.properties index ef97e089..75d6c668 100644 --- a/preprod.properties +++ b/preprod.properties @@ -46,3 +46,10 @@ md.dist.path.name=/ # mdq.dist.name=mdq-test.ukfederation.org.uk mdq.cache=mdqcache-test.tar.gz + +# +# Preprod T&I CDI uses different settings for temp location and +# +cdi-master.temploc.name=/tmp/legacy-ukf-test +cdi-master.md.path.name=/legacy-ukf-test-md/ +cdi-master.mdq.path.name=/legacy-ukf-test-mdq/ From 6b112f45dfaf79487eb372d99fc59cf64d6ce341 Mon Sep 17 00:00:00 2001 From: Rhys Smith Date: Tue, 13 Nov 2018 15:21:38 +0000 Subject: [PATCH 59/63] Fix issue with verifying remote MDQ all entities on CDI-master --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 70267e83..e5327caf 100644 --- a/build.xml +++ b/build.xml @@ -1384,7 +1384,7 @@ --> Verifying MDQ held at ${cdi-master.name}${cdi-master.mdq.path.name} - + Verifying MDQ held at ${mdq.dist.name} From 2122eb7334b0f0154c6915e9c1d5086de81d5268 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 26 Nov 2018 10:47:40 +0000 Subject: [PATCH 60/63] Allow WARN messages to be flagged for the import pipeline Resolves ukf/ukf-meta#169. --- mdx/common-beans.xml | 15 +++++++++++++++ mdx/uk/verbs.xml | 3 +++ 2 files changed, 18 insertions(+) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index 786e0159..e77b3776 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -464,6 +464,21 @@ + + + + + + #{T(net.shibboleth.metadata.WarningStatus)} + + + + + + From d8fcd5a1c5a39ad01e02141493526fa1c620082b Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 6 Dec 2018 12:14:13 +0000 Subject: [PATCH 61/63] Convert tabs to spaces --- utilities/check_embedded.pl | 628 ++++++++++++++++++------------------ 1 file changed, 314 insertions(+), 314 deletions(-) diff --git a/utilities/check_embedded.pl b/utilities/check_embedded.pl index 6919014b..01dbbcad 100755 --- a/utilities/check_embedded.pl +++ b/utilities/check_embedded.pl @@ -32,20 +32,20 @@ my $longExpiredDays = 30*3; # about three months sub error { - my($s) = @_; - push(@olines, ' *** ' . $s . ' ***'); - $printme = 1; + my($s) = @_; + push(@olines, ' *** ' . $s . ' ***'); + $printme = 1; } sub warning { - my ($s) = @_; - push(@olines, ' ' . $s); - $printme = 1; + my ($s) = @_; + push(@olines, ' ' . $s); + $printme = 1; } sub comment { - my($s) = @_; - push(@olines, ' (' . $s . ')'); + my($s) = @_; + push(@olines, ' (' . $s . ')'); } # @@ -105,211 +105,211 @@ sub comment { while (<>) { - # - # Discard blank lines. - # - next if /^\s*$/; - - # - # Handle Entity/KeyName header line. - # - if (/^Entity:/) { - @olines = (); - $printme = 0; - @args = split; - $entity = $args[1]; - $keyname = $args[3]; - - # - # Tidy entity ID if it includes a UK ID as well. - # - if ($entity =~ /^\[(.+)\](.+)$/) { - $entity = $2 . ' (' . $1 . ')'; - } - - # - # Output header line. - # - $oline = "Entity $entity"; - $hasKeyName = !($keyname eq '(none)'); - push(@olines, $oline); - if ($hasKeyName) { - error("descriptor has unexpected KeyName $keyname"); - } - - # - # Start building a new blob. - # - # The blob contains the entity name, so de-duplication - # only occurs within a particular entity and not across - # entities. - # - $blob = $oline; - - # - # Create a temporary file for this certificate in PEM format. - # - ($fh, $filename) = tempfile(UNLINK => 1); - #print "temp file is: $filename\n"; - - # do not buffer output to the temporary file - select((select($fh), $|=1)[0]); - next; - } - - # - # Put other lines into a temporary file. - # - print $fh $_; - $blob .= '|' . $_; - - # - # If this is the last line of the certificate, actually do - # something with it. - # - if (/END CERTIFICATE/) { - # - # Have we seen this blob before? If so, close (and delete) the - # temporary file, and go and look for a new certificate to process. - # - $total_certs++; - if (defined($blobs{$blob})) { - # print "skipping a blob\n"; - close $fh; - next; - } - - # - # Otherwise, remember this blob so that we won't process it again. - # - $blobs{$blob} = 1; - $distinct_certs++; - - # - # Don't close the temporary file yet, because that would cause it - # to be deleted. We've already arranged for buffering to be - # disabled, so the file can simply be passed to other applications - # as input, perhaps multiple times. - # - - # - # Collection of names this certificate contains - # - my %names; - - # - # Use openssl to convert the certificate to text - # - my(@lines, $subject, $issuer, $subjectCN, $issuerCN, $fingerprint); - $cmd = "openssl x509 -in $filename -noout -text -nameopt RFC2253 -modulus -fingerprint|"; - open(SSL, $cmd) || die "could not open openssl subcommand"; - while () { - push @lines, $_; - - if (/^\s*Issuer:\s*(.*)$/) { - $issuer = $1; - if ($issuer =~ /CN=([^,]+)/) { - $issuerCN = $1; - } elsif ($issuer =~ /,OU=VeriSign International Server CA - Class 3,/) { - $issuerCN = 'VeriSign International Server CA - Class 3'; - } else { - $issuerCN = $issuer; - } - next; - } - - if (/^\s*Subject:\s*(.*)$/) { - $subject = $1; - if ($subject =~ /CN=([^,]+)/) { - $subjectCN = $1; - $names{lc $subjectCN}++; - } else { - $subjectCN = $1; - } - next; - } - - # - # Extract the certificate fingerprint. - # - if (/^\s*SHA1 Fingerprint=(.+)$/) { - $fingerprint = uc $1; - if (defined($expiry_whitelist{$fingerprint})) { - $expiry_whitelist{$fingerprint} = 'used'; - } - } - - # - # Extract the public key size. This is displayed differently - # in different versions of OpenSSL. - # - if (/RSA Public Key: \((\d+) bit\)/) { # OpenSSL 0.9x - $pubSize = $1; - next; - } elsif (/^\s*Public-Key: \((\d+) bit\)/) { # OpenSSL 1.0 - $pubSize = $1; - next; - } - - if (/Not After : (.*)$/) { - $notAfter = $1; - $notAfterTime = str2time($notAfter); - - # - # Track certificate expiry year in a way that doesn't - # involve Unix epoch overflow. - # - if ($notAfter =~ /(\d\d\d\d)/) { - my $year = $1; - if ($year > $maxYear) { - $maxYear = $year; - } - if ($year >= 2038) { - $num2038++; - } - } - - # - # Track most distant notAfter. - # - if ($notAfterTime > $lastNotAfterTime) { - $lastNotAfter = $notAfter; - $lastNotAfterTime = $notAfterTime; - $lastNotAfterEntity = $entity; - } - - $days = ($notAfterTime-time())/86400.0; - next; - } - - # - # subjectAlternativeName - # - if (/X509v3 Subject Alternative Name:/) { - # - # Steal the next line, which will look like this: - # - # DNS:www.example.co.uk, DNS:example.co.uk, URI:http://example.co.uk/ - # - my $next = ; - - # - # Make an array of components, each something like "DNS:example.co.uk" - # - $next =~ s/\s*//g; - my @altNames = split /\s*,\s*/, $next; - # my $altSet = "{" . join(", ", @altNames) . "}"; - # print "Alt set: $altSet\n"; - - # - # Each "DNS" component is an additional name for this certificate. - # - while (@altNames) { - my ($type, $altName) = split(":", pop @altNames); - $names{lc $altName}++ if $type eq 'DNS'; - } - next; - } + # + # Discard blank lines. + # + next if /^\s*$/; + + # + # Handle Entity/KeyName header line. + # + if (/^Entity:/) { + @olines = (); + $printme = 0; + @args = split; + $entity = $args[1]; + $keyname = $args[3]; + + # + # Tidy entity ID if it includes a UK ID as well. + # + if ($entity =~ /^\[(.+)\](.+)$/) { + $entity = $2 . ' (' . $1 . ')'; + } + + # + # Output header line. + # + $oline = "Entity $entity"; + $hasKeyName = !($keyname eq '(none)'); + push(@olines, $oline); + if ($hasKeyName) { + error("descriptor has unexpected KeyName $keyname"); + } + + # + # Start building a new blob. + # + # The blob contains the entity name, so de-duplication + # only occurs within a particular entity and not across + # entities. + # + $blob = $oline; + + # + # Create a temporary file for this certificate in PEM format. + # + ($fh, $filename) = tempfile(UNLINK => 1); + #print "temp file is: $filename\n"; + + # do not buffer output to the temporary file + select((select($fh), $|=1)[0]); + next; + } + + # + # Put other lines into a temporary file. + # + print $fh $_; + $blob .= '|' . $_; + + # + # If this is the last line of the certificate, actually do + # something with it. + # + if (/END CERTIFICATE/) { + # + # Have we seen this blob before? If so, close (and delete) the + # temporary file, and go and look for a new certificate to process. + # + $total_certs++; + if (defined($blobs{$blob})) { + # print "skipping a blob\n"; + close $fh; + next; + } + + # + # Otherwise, remember this blob so that we won't process it again. + # + $blobs{$blob} = 1; + $distinct_certs++; + + # + # Don't close the temporary file yet, because that would cause it + # to be deleted. We've already arranged for buffering to be + # disabled, so the file can simply be passed to other applications + # as input, perhaps multiple times. + # + + # + # Collection of names this certificate contains + # + my %names; + + # + # Use openssl to convert the certificate to text + # + my(@lines, $subject, $issuer, $subjectCN, $issuerCN, $fingerprint); + $cmd = "openssl x509 -in $filename -noout -text -nameopt RFC2253 -modulus -fingerprint|"; + open(SSL, $cmd) || die "could not open openssl subcommand"; + while () { + push @lines, $_; + + if (/^\s*Issuer:\s*(.*)$/) { + $issuer = $1; + if ($issuer =~ /CN=([^,]+)/) { + $issuerCN = $1; + } elsif ($issuer =~ /,OU=VeriSign International Server CA - Class 3,/) { + $issuerCN = 'VeriSign International Server CA - Class 3'; + } else { + $issuerCN = $issuer; + } + next; + } + + if (/^\s*Subject:\s*(.*)$/) { + $subject = $1; + if ($subject =~ /CN=([^,]+)/) { + $subjectCN = $1; + $names{lc $subjectCN}++; + } else { + $subjectCN = $1; + } + next; + } + + # + # Extract the certificate fingerprint. + # + if (/^\s*SHA1 Fingerprint=(.+)$/) { + $fingerprint = uc $1; + if (defined($expiry_whitelist{$fingerprint})) { + $expiry_whitelist{$fingerprint} = 'used'; + } + } + + # + # Extract the public key size. This is displayed differently + # in different versions of OpenSSL. + # + if (/RSA Public Key: \((\d+) bit\)/) { # OpenSSL 0.9x + $pubSize = $1; + next; + } elsif (/^\s*Public-Key: \((\d+) bit\)/) { # OpenSSL 1.0 + $pubSize = $1; + next; + } + + if (/Not After : (.*)$/) { + $notAfter = $1; + $notAfterTime = str2time($notAfter); + + # + # Track certificate expiry year in a way that doesn't + # involve Unix epoch overflow. + # + if ($notAfter =~ /(\d\d\d\d)/) { + my $year = $1; + if ($year > $maxYear) { + $maxYear = $year; + } + if ($year >= 2038) { + $num2038++; + } + } + + # + # Track most distant notAfter. + # + if ($notAfterTime > $lastNotAfterTime) { + $lastNotAfter = $notAfter; + $lastNotAfterTime = $notAfterTime; + $lastNotAfterEntity = $entity; + } + + $days = ($notAfterTime-time())/86400.0; + next; + } + + # + # subjectAlternativeName + # + if (/X509v3 Subject Alternative Name:/) { + # + # Steal the next line, which will look like this: + # + # DNS:www.example.co.uk, DNS:example.co.uk, URI:http://example.co.uk/ + # + my $next = ; + + # + # Make an array of components, each something like "DNS:example.co.uk" + # + $next =~ s/\s*//g; + my @altNames = split /\s*,\s*/, $next; + # my $altSet = "{" . join(", ", @altNames) . "}"; + # print "Alt set: $altSet\n"; + + # + # Each "DNS" component is an additional name for this certificate. + # + while (@altNames) { + my ($type, $altName) = split(":", pop @altNames); + $names{lc $altName}++ if $type eq 'DNS'; + } + next; + } # # Track distinct RSA moduli @@ -319,114 +319,114 @@ sub comment { # print " modulus: '$modulus'\n"; $rsa_modulus{$modulus} = 1; } - } - close SSL; - #print " text lines: $#lines\n"; - - # - # Deal with certificate expiry. - # - if ($days < -$longExpiredDays) { - my $d = floor(-$days); - if (defined($expiry_whitelist{$fingerprint})) { - comment("EXPIRED LONG AGO ($d days; $notAfter)"); - } else { - error("EXPIRED LONG AGO ($d days; $notAfter)"); - comment("fingerprint $fingerprint"); - } - } elsif ($days < 0) { - if (defined($expiry_whitelist{$fingerprint})) { - comment("EXPIRED ($notAfter)"); - } else { - error("EXPIRED ($notAfter)"); - comment("fingerprint $fingerprint"); - } - } elsif ($days < $daysBeforeError) { - $days = int($days); - error("expires in $days days ($notAfter)"); - } elsif ($days < $daysBeforeWarning) { - $days = int($days); - warning("expires in $days days ($notAfter)"); - } - - - # - # Handle public key size. - # - $pubSizeCount{$pubSize}++; - # print " Public key size: $pubSize\n"; - - # - # Close the temporary file, which will also cause - # it to be deleted. - # - close $fh; - - # - # Count issuers. - # - if ($issuer eq $subject) { - $issuers{'(self-signed certificate)'}++; - } else { - $issuers{'Other'}++; - } - - # - # Print any interesting things related to this certificate. - # - if ($printme) { - foreach $oline (@olines) { - print $oline, "\n"; - } - print "\n"; - } - - } + } + close SSL; + #print " text lines: $#lines\n"; + + # + # Deal with certificate expiry. + # + if ($days < -$longExpiredDays) { + my $d = floor(-$days); + if (defined($expiry_whitelist{$fingerprint})) { + comment("EXPIRED LONG AGO ($d days; $notAfter)"); + } else { + error("EXPIRED LONG AGO ($d days; $notAfter)"); + comment("fingerprint $fingerprint"); + } + } elsif ($days < 0) { + if (defined($expiry_whitelist{$fingerprint})) { + comment("EXPIRED ($notAfter)"); + } else { + error("EXPIRED ($notAfter)"); + comment("fingerprint $fingerprint"); + } + } elsif ($days < $daysBeforeError) { + $days = int($days); + error("expires in $days days ($notAfter)"); + } elsif ($days < $daysBeforeWarning) { + $days = int($days); + warning("expires in $days days ($notAfter)"); + } + + + # + # Handle public key size. + # + $pubSizeCount{$pubSize}++; + # print " Public key size: $pubSize\n"; + + # + # Close the temporary file, which will also cause + # it to be deleted. + # + close $fh; + + # + # Count issuers. + # + if ($issuer eq $subject) { + $issuers{'(self-signed certificate)'}++; + } else { + $issuers{'Other'}++; + } + + # + # Print any interesting things related to this certificate. + # + if ($printme) { + foreach $oline (@olines) { + print $oline, "\n"; + } + print "\n"; + } + + } } if ($distinct_certs > 1) { - print "Total certificates: $total_certs\n"; - if ($distinct_certs != $total_certs) { - print "Distinct certificate/entity combinations: $distinct_certs\n"; - } - print "\n"; - - print "Key size distribution:\n"; - for $pubSize (sort keys %pubSizeCount) { - $count = $pubSizeCount{$pubSize}; - print " $pubSize: $count\n"; - } - print "\n"; - - print "Most distant certificate expiry: $lastNotAfter on $lastNotAfterEntity\n"; - print "Maximum certificate expiry year: $maxYear\n"; - if ($num2038 > 0) { - print "Certificates expiring during or after 2038: $num2038\n"; - } - print "\n"; - - print "Certificate issuers:\n"; - foreach $issuer (sort keys %issuers) { - my $count = $issuers{$issuer}; - my $mark = $issuerMark{$issuer} ? $issuerMark{$issuer}: ' '; - print " $mark $issuer: $count\n"; - } - print "\n"; + print "Total certificates: $total_certs\n"; + if ($distinct_certs != $total_certs) { + print "Distinct certificate/entity combinations: $distinct_certs\n"; + } + print "\n"; + + print "Key size distribution:\n"; + for $pubSize (sort keys %pubSizeCount) { + $count = $pubSizeCount{$pubSize}; + print " $pubSize: $count\n"; + } + print "\n"; + + print "Most distant certificate expiry: $lastNotAfter on $lastNotAfterEntity\n"; + print "Maximum certificate expiry year: $maxYear\n"; + if ($num2038 > 0) { + print "Certificates expiring during or after 2038: $num2038\n"; + } + print "\n"; + + print "Certificate issuers:\n"; + foreach $issuer (sort keys %issuers) { + my $count = $issuers{$issuer}; + my $mark = $issuerMark{$issuer} ? $issuerMark{$issuer}: ' '; + print " $mark $issuer: $count\n"; + } + print "\n"; $distinct_moduli = scalar keys %rsa_modulus; if ($distinct_moduli > 1) { print "Distinct RSA moduli: $distinct_moduli\n"; } - my $first = 1; - foreach $fingerprint (sort keys %expiry_whitelist) { - if ($expiry_whitelist{$fingerprint} eq 'unused') { - if ($first) { - $first = 0; - print "\n"; - print "Unused expiry whitelist fingerprints:\n"; - } - print " $fingerprint\n"; - } - } + my $first = 1; + foreach $fingerprint (sort keys %expiry_whitelist) { + if ($expiry_whitelist{$fingerprint} eq 'unused') { + if ($first) { + $first = 0; + print "\n"; + print "Unused expiry whitelist fingerprints:\n"; + } + print " $fingerprint\n"; + } + } } From 4619daa5e0fb33b4b571c03a03dcb8bd4991eae3 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Thu, 6 Dec 2018 12:28:08 +0000 Subject: [PATCH 62/63] Report expiry whitelist size --- utilities/check_embedded.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utilities/check_embedded.pl b/utilities/check_embedded.pl index 01dbbcad..f630b871 100755 --- a/utilities/check_embedded.pl +++ b/utilities/check_embedded.pl @@ -418,12 +418,16 @@ sub comment { print "Distinct RSA moduli: $distinct_moduli\n"; } + if (%expiry_whitelist) { + print "\n"; + my $nwhite = scalar(keys(%expiry_whitelist)); + print "Expiry whitelist size: $nwhite\n"; + } my $first = 1; foreach $fingerprint (sort keys %expiry_whitelist) { if ($expiry_whitelist{$fingerprint} eq 'unused') { if ($first) { $first = 0; - print "\n"; print "Unused expiry whitelist fingerprints:\n"; } print " $fingerprint\n"; From 84170889bea058e9176994f382851ce111c753b1 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Tue, 18 Dec 2018 11:38:23 +0000 Subject: [PATCH 63/63] Treat DSA keys in metadata as errors See ukf/ukf-meta#117. --- mdx/common-beans.xml | 3 +++ mdx/uk/beans.xml | 3 +++ mdx/uk/verbs.xml | 3 +++ .../{ukf-mda-0.9.7.jar => ukf-mda-0.9.8.jar} | Bin 59089 -> 60825 bytes 4 files changed, 9 insertions(+) rename tools/ukf-mda/{ukf-mda-0.9.7.jar => ukf-mda-0.9.8.jar} (51%) diff --git a/mdx/common-beans.xml b/mdx/common-beans.xml index e77b3776..7e33f0f0 100644 --- a/mdx/common-beans.xml +++ b/mdx/common-beans.xml @@ -1073,6 +1073,9 @@ + + + diff --git a/mdx/uk/beans.xml b/mdx/uk/beans.xml index 38cb1cfa..30fd7d53 100644 --- a/mdx/uk/beans.xml +++ b/mdx/uk/beans.xml @@ -368,6 +368,9 @@ + + + diff --git a/mdx/uk/verbs.xml b/mdx/uk/verbs.xml index a18c761c..c5a88d82 100644 --- a/mdx/uk/verbs.xml +++ b/mdx/uk/verbs.xml @@ -335,6 +335,9 @@ + + + diff --git a/tools/ukf-mda/ukf-mda-0.9.7.jar b/tools/ukf-mda/ukf-mda-0.9.8.jar similarity index 51% rename from tools/ukf-mda/ukf-mda-0.9.7.jar rename to tools/ukf-mda/ukf-mda-0.9.8.jar index f0df7fd5fe10083f9fbb9d58fb040e61ca3c67ca..7e6728839f03ae69aeb98803eb382164d0471cc0 100644 GIT binary patch delta 13936 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 delta 12461 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