#!/usr/bin/perl # ezpwebserv.cgi # (c) 1999-2005 Useful Utilities # http://www.usefulutilities.com # # Revised April 2005 to use qurl to pass URL from EZproxy to this # script and back to EZproxy using URL encoding. use Socket; use Time::Local; # This script simply connects back to the EZproxy server and starts a new # session. It's perfect for use if you can configure your web server # to authenticate your users before running this script. # To link EZproxy to this script, you need to make an entry in ezproxy.usr # that looks like: # # cgiuser:cgipass:qcgi=http://auth.mylib.org/cgi-bin/ezpwebserv.cgi? # # This line indicates that all new authentication requests should be # handed off to the specified CGI script. The ? at the end is required # since EZproxy will then append qurl= followed by the web site the # user wants to visit. # # $ezpuser and $ezppass have to be set to match the username and password # from the ezproxy.usr entry. $ezphost must be your EZproxy server's # host name. $ezpuser = "cgiuser"; $ezppass = "cgipass"; $ezphost = "ezproxy.mylib.org"; $action = $0; $action =~ s/^.*[\/\\]//g; $ezpport = 2048; $| = 1; ParseFields(); # If you want EZproxy to log this username, add "O LOGUSER" to ezproxy.cfg, # uncomment the next line, and change as relevant to provide user to log # $ezploguser = $ENV{"REMOTE_USER"}; StartSession(); sub Debug { return if $debugFile eq ""; if ($debugOpen != 1) { open(DEBUG, ">>$debugFile") || return; $debugOpen = 1; } flock(DEBUG, LOCK_EX); seek(DEBUG, 0, 2); print DEBUG $_[0]; flock(DEBUG, LOCK_UN); } sub Down { Debug("$_[0]\n"); print "Content-type: text/html\n\n"; print $_[0], "\n"; exit(1); } sub FormEncode { my $temp = $_[0]; $temp =~ s/([&'"])/sprintf("&#%d;",ord($1))/ge; return $temp; } sub URLEncode { my $temp = $_[0]; $temp =~ s/([^A-Za-z0-9])/sprintf("%%%2X", ord($1))/eg; $temp =~ s/%20/+/g; return $temp; } sub ParseFields { my $in, $fieldval, $field, $val, $count; %in = (); if ($ENV{"REQUEST_METHOD"} eq "GET") { $in = $ENV{"QUERY_STRING"}; } elsif ($ENV{"REQUEST_METHOD"} eq "POST") { # In a POST, no special processing of URL is required read(STDIN, $in, $ENV{"CONTENT_LENGTH"}); } else { return 0; } $count = 0; foreach $fieldval (split(/&/, $in)) { $fieldval =~ s/\+/ /g; ($field, $val) = split(/=/, $fieldval, 2); $val =~ s/%([0-9a-fA-F]{2})/pack("c",hex($1))/ge; # Remove inresult characters $val =~ s/[^!-~]//g; $in{$field} = $val; $count++; } if (defined $in{"qurl"}) { $ezpurl = $in{"qurl"} }; return $count; } sub MakeConnection { my $fh, $host, $port, $proto, $proto, $oldfh; ($fh, $host, $port) = @_; if ($host =~ s/:(\d+)$//) { $port = $1; } $proto = getprotobyname('tcp'); $iaddr = inet_aton($host) || Down("Unable to lookup host $host: $!"); $paddr = sockaddr_in($port, $iaddr); socket($fh, PF_INET, SOCK_STREAM, $proto) || Down("Unable to create socket: $!"); connect($fh, $paddr) || Down("Unable to connect to $host:$port: $!"); $oldfh = select($fh); $| = 1; select($oldfh); } sub StartSession { my $query; $query = "?user=" . URLEncode($ezpuser) . "&pass=" . URLEncode($ezppass); # If the calling script has set $ezploguser, pass this value to EZproxy # to log to the ezproxy.log file. Note that your ezproxy.cfg must also # contain "O LOGUSER" to enable this feature. if ($ezploguser ne "") { $query .= "&loguser=" . URLEncode($ezploguser); } if ($ezpurl ne "") { $query .= "&qurl=" . URLEncode($ezpurl); } MakeConnection(EZPROXY, $ezphost, $ezpport); print EZPROXY "GET /login$query HTTP/1.0\n\n"; $skip = ; print while ; close(EZPROXY); }