#! /usr/local/bin/perl -w
use strict;
$| = 1;
use CGI qw/:standard/;
my $DEBUG = param('d') || 0;
print header(), start_html("Protected by a client side cert"),
h1("Protected by a client side cert");
if(my $user = verify_cert()) {
print "Welcome $user, you are authorized.";
print "
Your ",%ENV->{'SSL_CLIENT_I_DN_O'}, " issued Certificate is valid.";
print "
View the source code.\n";
} else {
print "NOT WELCOME, you are not authorized.\n";
}
print "
Date: " . localtime(), "\n";
print end_html();
print "\n";
exit;
sub verify_cert {
# This routine could get arbitrarily complex. This version verifies
# that the certificate was issued by Dartmouth, issued to Dartmouth,
# and (optionally) that the organization the certificate was issued
# to matches a regular expression.
#
# It returns the name of the person the cert was issued to, or undef
# if not authorized.
my $department_regex = shift || "";
# Check that these enviroment variables at least exist
my @must_exist = (
'SSL_CLIENT_CERT',
'SSL_CLIENT_I_DN_O',
'SSL_CLIENT_S_DN_O',
'SSL_CLIENT_S_DN_CN',
# 'SSL_CLIENT_S_DN_OU',
'SSL_CIPHER',
);
foreach my $env (@must_exist) {
debug("Checking the existence of: $env, ");
if (!defined(%ENV->{$env}) || %ENV->{$env} eq "") {
debug("FAILED\n
");
return undef;
}
debug("passed.
\n");
}
# SSL_CIPHER: the cipher used for encryption
debug("Checking contents of: SSL_CIPHER, ");
if(%ENV->{'SSL_CIPHER'} =~ m/^(EXP|NULL)-/) {
debug("FAILED (", %ENV->{'SSL_CIPHER'} ,")\n
");
return undef;
}
debug("passed.
\n");
# SSL_CLIENT_I_DN_O is the Organization that issued the certificate
debug("Checking contents of: SSL_CLIENT_I_DN_O, ");
if(%ENV->{'SSL_CLIENT_I_DN_O'} ne "Dartmouth College") {
debug("FAILED (", %ENV->{'SSL_CLIENT_I_DN_O'} ,")\n
");
return undef;
}
debug("passed.
\n");
# SSL_CLIENT_S_DN_O is the Organization that the certificate was
# issued for.
debug("Checking contents of SSL_CLIENT_S_DN_O, ");
if(%ENV->{'SSL_CLIENT_S_DN_O'} ne "Dartmouth College") {
debug("FAILED (", %ENV->{'SSL_CLIENT_S_DN_O'} ,")\n
");
return undef;
}
debug("passed.
\n");
# SSL_CLIENT_S_DN_OU is the Organizational Unit that the certificate was
# issued for.
if ($department_regex) {
debug("Checking contents of SSL_CLIENT_S_DN_OU against regex $department_regex, ");
if (! %ENV->{'SSL_CLIENT_S_DN_OU'} ||
%ENV->{'SSL_CLIENT_S_DN_OU'} !~ m/$department_regex/) {
debug("FAILED (", %ENV->{'SSL_CLIENT_I_DN_OU'} ,")\n
");
return undef;
}
debug("passed.
\n");
}
debug("All checks passed, returning contents of SSL_CLIENT_S_DN_CN: ",
%ENV->{'SSL_CLIENT_S_DN_CN'}, "
");
# SSL_CLIENT_S_DN_CN is the user that the certificate belongs to.
return %ENV->{'SSL_CLIENT_S_DN_CN'};
}
sub debug {
my @output = @_;
if($DEBUG && $DEBUG > 0) {
print @_;
}
}