#! /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 @_; } }