#!/usr/bin/perl -w # # authenticate.pl # # Code based from Eric Bivona's sidecar.pl and Omen Wild's # SSL authentication example from the PKI Lab's website # at http://www.dartmouth.edu/~pkilab # Checks first to see if a user has a valid cert in the # environment variables. If it does not, then it sends a # Sidecar request to the client. # If the script authenticates the user, then it starts sending # the file specified as part of the called URL back to the # client. # # Copyright 1996-2004 by the Trustees of Dartmouth College # require 5.002; use strict; use CGI; use CUSSP; my ($I_DN_O, $S_DN_O) = ("Dartmouth College", "Dartmouth College"); my ($error_email) = "webmaster\@dartmouth.edu"; my ($page_title) = "Dartmouth College Software Downloads"; 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) { if (!defined($ENV{$env}) || $ENV{$env} eq "") { return undef; } } # SSL_CIPHER: the cipher used for encryption if($ENV{'SSL_CIPHER'} =~ m/^(EXP|NULL)-/) { return undef; } # SSL_CLIENT_I_DN_O is the Organization that issued the certificate if($ENV{'SSL_CLIENT_I_DN_O'} ne $I_DN_O) { return undef; } # SSL_CLIENT_S_DN_O is the Organization that the certificate was # issued for. if($ENV{'SSL_CLIENT_S_DN_O'} ne $S_DN_O) { return undef; } # SSL_CLIENT_S_DN_OU is the Organizational Unit that the certificate was # issued for. if ($department_regex) { if ($ENV{'SSL_CLIENT_S_DN_OU'} !~ m/$department_regex/) { return undef; } } # SSL_CLIENT_S_DN_CN is the user that the certificate belongs to. return $ENV{'SSL_CLIENT_S_DN_CN'}; } sub verify_kerb { my ($rc, $em, %tckt, $key, $val); ($rc, $em, %tckt) = CUSSP::GetK4Ticket("WWW-agent", "WWW", $ENV{'REMOTE_ADDR'}, undef, $ENV{'REMOTE_PORT'}, 120); if ($rc) { return undef; } else { return $tckt{'name'}; } } { my ($cgi) = new CGI; my ($name); if ( (!defined($name = verify_cert())) && (!defined($name = verify_kerb()))) { # Authentication failed print($cgi->header(-type => "text/html"), $cgi->start_html(-title => $page_title, -author => $error_email, -base => undef)); print ("