-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpropagate.pl
executable file
·145 lines (121 loc) · 4.2 KB
/
propagate.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/perl -w
#
# Script to measure metadata propagation
#
# Author: Alex Stuart, [email protected]
#
$| = 1;
use Getopt::Long;
my $interval_d = 300; # 5 minutes default repeat interval
sub usage {
my $message = shift(@_);
if ($message) { print "\n$message\n"; }
print <<EOF;
usage: $0 [-h] [-v] [-i <interval>] -r <RequestInitiator> \\
[-f <file> | -e <IdP entityID> [-e <IdP entityID> ...]]
Script to measure metadata propagation
-r <RequestInitiator> - RequestInitiator to use
-i <interval> - number of seconds between repeats (default is $interval_d)
-e <IdP entityID> - 1 or more IdP entityIDs to check (multiple -e options allowed)
-f <file> - read list of entityIDs from file, one entityID per line
-h - print this help text and exit
-v - be verbose
This script issues curl commands to the RequestInitiator, asking for an AuthnRequest
to be sent to the specified IdP entityID(s). The IdPs are presumed to be Shibboleth v3
so the HTTP status code of the request is:
200 (OK) if the SP recognises both the IdP entityID and the AssertionConsumerService endpoint
500 (Server Error) if the AssertionConsumerService endpoint isn't recognised (jetty hosted)
400 (Bad Request) if the AssertionConsumerService endpoint isn't recognised (http+tomcat)
The output of the script is a series of lines: timestamp, entityID, return code
The way to measure propagation time is to:
1) Register an SP's metadata
2) Configure the SP to have an AssertionConsumerService endpoint that is not in metadata
3) Set this script running. You should find the output is HTTP status 400/500
4) Register the new endpoint
5) Watch the output as the IdP recognises the SP's new endpoint (and HTTP status goes to 200)
EOF
}
my $help;
my $RequestInitiator;
my $verbose;
my @entityIDs;
my $interval;
my $file;
GetOptions( "help" => \$help,
"requestinitiator=s" => \$RequestInitiator,
"verbose" => \$verbose,
"entityIDs=s" => \@entityIDs,
"interval=i" => \$interval,
"file=s" => \$file
);
if ( $help ) {
usage;
exit 0;
}
if ( ! $RequestInitiator ) {
usage( "ERROR: must supply a RequestInitiator with -r" );
exit 1;
}
if ( ! $interval ) { $interval = $interval_d; }
#
# Populate array of entityIDs either from multiple -e options or from the file specified by -f
#
if ( @entityIDs && $file ) {
usage( "ERROR: cannot have both -e and -f options to define entityIDs" );
exit 1;
}
if ( $file ) {
open(ENTITYIDS, "<", "$file") || die "Cannot open file of entityIDs for reading, $file";
while(<ENTITYIDS>) {
if (/^\s*#/) { next; }
chomp;
s/,.*//;
push @entityIDs, $_;
}
close(ENTITYIDS);
}
if ( $#entityIDs == -1 ) {
usage( "ERROR: must specify at least one entityID using -e or -f options" );
exit 1;
}
$verbose && print "Script running in verbose mode\n";
$verbose && print "RequestInitiator: $RequestInitiator\n";
if ( $verbose ) { foreach (@entityIDs) { print "entityID: $_\n"; } }
$verbose && print "Repeat interval: $interval\n";
sub doTheThing {
my $RequestInitiator = shift;
my $entityID = shift;
my $now;
my $curloutput;
$encodedID = $entityID;
$encodedID =~ s!:!%3A!g;
$encodedID =~ s!/!%2F!g;
$verbose && print "Checking $entityID\n";
open(TIME, 'date -u "+%Y-%m-%dT%H:%M:%SZ" |') || warn "cannot find date";
while (<TIME>) { chomp; $now .= $_; }
close(TIME);
$verbose && print "$now\n";
# curl flags are ordered so that -o and -w can be omitted when cutting and pasting output from -v
$theCommand = 'curl --connect-timeout 3 -k --silent -L -c /tmp/cookies.txt ' . $RequestInitiator . '?entityID=' . $encodedID .
' -o /dev/null -w "' . $now. ', ' . $entityID . ', %{http_code}\n"';
$verbose && print "$theCommand\n";
open (FILE, "$theCommand |") || warn "Cannot get the curl command to work";
while (<FILE>) { $curloutput .= $_; }
close (FILE);
$curloutput =~ m!\s(\S+)$!;
$retval = $1;
$verbose && print "HTTP return value: $retval\n";
print $curloutput;
return $retval
}
while ($#entityIDs != -1) {
undef @nextentityIDs;
foreach $entityID (@entityIDs) {
$retval = doTheThing( $RequestInitiator, $entityID );
if ( $retval != 200 ) {
push @nextentityIDs, $entityID;
}
}
@entityIDs = @nextentityIDs;
sleep $interval;
}