|
|
|
#!/usr/bin/perl -w
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
use Getopt::Long;
|
|
|
|
use LWP::Simple qw($ua getstore);
|
|
|
|
use Net::Domain qw(hostname hostfqdn hostdomain domainname);
|
|
|
|
use Mail::Sendmail;
|
|
|
|
|
|
|
|
my $cert;
|
|
|
|
my $ca = '/etc/radius/certs/ca.pem';
|
|
|
|
my $crl;
|
|
|
|
my $issuer;
|
|
|
|
my $notify_crl;
|
|
|
|
|
|
|
|
GetOptions(
|
|
|
|
'certificate=s' => \$cert,
|
|
|
|
'cacert=s' => \$ca,
|
|
|
|
'crl=s' => \$crl,
|
|
|
|
'notify-crl=s' => \$notify_crl,
|
|
|
|
'issuer=s' => \$issuer
|
|
|
|
);
|
|
|
|
|
|
|
|
# Set a 5 sec timeout to fetch the CRL
|
|
|
|
$ua->timeout(5);
|
|
|
|
|
|
|
|
my $crl_file;
|
|
|
|
my $crl_age;
|
|
|
|
if ($crl){
|
|
|
|
if ($crl =~ m{^/} && -e $crl){
|
|
|
|
$crl_file = $crl;
|
|
|
|
$crl_age = time - ( stat($crl) )[9];
|
|
|
|
} elsif ($crl =~ m{^https?://}) {
|
|
|
|
$crl_age = 9999999;
|
|
|
|
|
|
|
|
if (-e '/run/radiusd/tls/crl.pem'){
|
|
|
|
$crl_age = time - ( stat('/run/radiusd/tls/crl.pem') )[9];
|
|
|
|
$crl_file = '/run/radiusd/tls/crl.pem';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!-e '/run/radiusd/tls/crl.pem' or $crl_age > 900){
|
|
|
|
my $code = getstore($crl,$crl_file);
|
|
|
|
if ($code == 200){
|
|
|
|
$crl_age = 0;
|
|
|
|
$crl_file = '/run/radiusd/tls/crl.pem';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined $crl and (not defined $crl_file or ($crl =~ m{https?://} and $crl_age > 7200))){
|
|
|
|
if (defined $notify_crl){
|
|
|
|
my %mail = (
|
|
|
|
To => $notify_crl,
|
|
|
|
From => 'radius@' . hostdomain(),
|
|
|
|
Subject => 'CRL issue',
|
|
|
|
Message => 'Authentication done with an outdated CRL'
|
|
|
|
);
|
|
|
|
sendmail(%mail);
|
|
|
|
} else {
|
|
|
|
die "CRL is too old or missing\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
my $cmd = "openssl verify -trusted $ca -purpose sslclient";
|
|
|
|
$cmd .= " -crl_check -CRLfile $crl_file" if (defined $crl_file);
|
|
|
|
$cmd .= " $cert";
|
|
|
|
my $ca_check = qx($cmd);
|
|
|
|
if ($? != 0){
|
|
|
|
print "openssl verify command returned non zero\n";
|
|
|
|
print $ca_check;
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
chomp($ca_check);
|
|
|
|
if ($ca_check !~ m/^$cert:\s+OK$/){
|
|
|
|
print "openssl failed to verify $cert against $ca\n";
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $expire_check = qx(openssl x509 -in $cert -checkend 0);
|
|
|
|
if ($? != 0 || $expire_check !~ m/^Certificate will not expire/){
|
|
|
|
print "certificate is expired\n";
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($issuer){
|
|
|
|
my $issuer_check = qx(openssl x509 -in $cert -noout -issuer);
|
|
|
|
chomp($issuer_check);
|
|
|
|
$issuer_check =~ s/^issuer=\s*//;
|
|
|
|
unless ($issuer_check eq $issuer){
|
|
|
|
print "Certificate is signed by $issuer_check instead of $issuer\n";
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exit 0;
|