RPAS Protocol, Requirements and Specifications
Remote Patron Authentication Service (RPAS) is a new SearchBank service which 
validates library patrons as they access SearchBank, using a Web browser, from 
anywhere on the internet. RPAS enhances the library’s value to their community 
by offering SearchBank services and databases to their patrons at home, in the 
dorm or while traveling.
When a remote user connects, SearchBank determines that their ip address is 
outside the range associated with the library. If the library is participating 
in RPAS, SearchBank prompts the user to enter their unique identifier (e.g. 
_Please enter your library card number_). SearchBank then presents the unique 
identifier to a library designated computer. The library computer uses the 
identifier to perform a lookup against a patron database (or file) and responds 
to SearchBank indicating whether the patron may access the service. If access is 
granted, SearchBank initiates a user session and displays the database menu 
page.
----------------------
Technical Requirements
To participate, a library must have access to a computer running a Web Server 
configured to run a CGI script and have a patron file available to verify users. 
DRA PAC customers are a special case -- they are not required to have a Web 
Server. 
IAC has developed a sample CGI script, written in perl, which extracts the 
patron identifier as sent by SearchBank and performs a simple lookup in the 
patron file. The Distribution Systems group is prepared to assist the library 
staff customize this script for their specific needs.
The following are required to use RPAS:
o An internet accessible Web server
o A perl or similar interpreter environment (with customization of the sample
  perl script to work in the library’s environment). Sample scripts are 
  available through Distribution Systems.
o A CGI  environment.
o Access to a list of patron identifiers.
o Provisions for periodic update of the patron file
------------------
Technical Overview
To determine validity of a patron-ID (or other authentication identifier) 
entered for access to the Web SearchBank, IAC’s servers will transmit HTTP/1.0 
requests to an HTTP server at the library’s installation. A CGI script or 
similar program on the library’s system will respond with a status code 
indicating whether access to the Web SearchBank should be allowed or denied.
Initially, NCSA basic authentication will be supported and IAC will transmit a 
username/password pair in the authorization header of its requests.
The SearchBank servers will make GET requests for URLs of the form:
	http://server-info/path-info/patron-info
where: 
server-info  indicates the host and port specification for the library’s HTTP 
             server
path-info    is the server-specific path to the CGI application that handles 
             remote patron authentication requests on the library’s system. 
patron-info 	is the authentication identifier (patron-ID) entered by the user 
             with any special characters %-escaped as required by the HTTP 
             protocol and URL syntax. Additional information, such as the IP 
             address of the user, may be included in this part of the URL if 
             required for authentication.
If the patron-ID specified in the URL exists and is allowed to access the Web 
SearchBank, the patron authentication CGI should return an HTTP 200 response 
with an arbitrary entity-body (arbitrary in the initial implementation; in the 
future, message bodies or multipart responses may be of a well-defined format 
and Content-Type). If patron-ID is not a known patron identifier for the 
library, a 253 (i.e. Not found) response should be returned by the HTTP 
server/CGI. If desired, a 254 response may be returned to indicate that a 
patron-ID is known but is not allowed Web SearchBank access, or 253 may be used 
to mean all forms of not authorized. 
IAC may cache responses for one day or more to reduce remote authentication 
overhead.
------------
Simple Flow:
          ---                                              ---
 ---     | L | < < (3) libserv/path/patronID              | S |    ---
(PID)----| W |--------------------------------------------| B |---(VIP)
 ---     | S | > > (4) Allow/     |   > >                 | S |    ---
          ---          Disallow   |  ^                     ---
                                  |  ^
                                  | (2) patronID
                                  |
                                  |          -----
                                  |         |  P  | (1)
                                   ` -------|  W  | ...searchbank/<locID>
                                            |  S  |
                                             -----
1. The patron (PWS) attempts to enter SearchBank through the library’s home 
   page or by using the SearchBank URL of the form
       searchbank.com/searchbank/locationID
2. The patron’s IP address is not recognized as a valid IP address (VIP) in 
   the library’s range so a request is made of the patron to enter a valid ID 
   number (patronID), and returned to the SearchBank server (SBS)
3. The ID number is appended to a URL, e.g. 
       HTTP:/lib.web.server/cgi_path/patronID
   and sent to the library’s web server (LWS).
4. The web server passes this URL to the CGI program, which parses the library 
   ID number and queries the library’s list of patron Ids (PID). If the ID is 
   valid, a positive response is sent back to IAC’s web server, giving 
   permission for the patron to access SearchBank. 
------------------
Sample Perl Script
Note: mailers can trash the formating of this script; a version is available
on ftp.iacenter.com. You man login anon and GET the file
	/anonymous_ftp/pub/iac/distribution/rpascript.pl

#!/usr/local/bin/perl
# *** URL parsing section
#
# This section of code processes the information provided by the web server
# process regarding the URL containing the RPA query. It may require
# modification for use on the library's system, or may simply require # tweaks to test 
things that can be reversed later.
# the next line shows all the information IAC can provide in a URL, for instance 
# a URL "/path-to-this-script/patron_id/browser_ip_address/browser_host_name/
# location_id
#($nothing, $patron_id, $ip_addr, $host_addr, $location) = split('/',$ENV{"PATH_INFO"});
# or use the next two lines for the simple case of only wanting a patron ID 
# (this is the typical case), e.g. "/path/patron_id"
$patron_id = $ENV{"PATH_INFO"};
$patron_id =~ s/^\///;
# these lines will open a log file "/tmp/prpa.log" for transactions received
#open (LOG, ">>/tmp/prpa.log");
#print LOG "RPA patron $patron_id of location $location at host $host_addr [$ip_a ddr]\n";
#close(LOG);
# This line will decode escape characters in the URL and allow processing of 
# special characters and spaces in IDs. Beware use of system commands unless 
# the security measure below is also used.
$patron_quoted = &decodeURL($patron_id);
if ($patron_quoted eq "") {
print "Status: 253\n\n";
print "No patron ID supplied, access denied\n"; exit;
}
# quote metacharacters (security)
# the 2nd line precedes any non-alphanumeric characters (0-9, a-z, A-Z, and _) # with a 
backslash to inhibit interpretation of the characters' potential
# special meanings
#
# NB: it follows that, unless these lines are commented out, patron ID's # may contain 
ONLY alphanumerics and underscores
#
# Dangerous operations with unquoted special characters include any calls # to external 
programs from within this perl script. This line may be
# commented out if this script calls no external programs or the programmer # concludes 
that such calls are safe from potentially dangerous character
# interpretations. The RPA system can handle any characters and will pass # anything the 
user enters to the designated RPA query URL. The potential # security exposure exists on 
the system answering replies, where this
# script is run. The sample script calls no external programs but comes # with this line 
activated to prevent accidental exposure of operating # system shells if the lookup 
section is modified.
#$patron_quoted =~ s/(\W)/\\\1/g;
# translate requested patron ID to lowercase (to force uppercase instead, # switch the 
positions of the "A-Z" and "a-z", or comment this line out
# to use case-sensitive comparisons)
$patron_quoted =~ tr/A-Z/a-z/;
open (LOG, ">>/tmp/prpa.log");
print LOG "RPA patron $patron_quoted of location $location at host $host_addr 
  [$ip_addr]\n";
close(LOG);
# *** ID lookup section
#
# This is the section that performs the ID lookup or other processing 
# required to determine if access to Web SearchBank should be granted 
# based in the information provided in the URL.
#
# put commands to get true or false answer for access here, setting
# $patron_id to 1 or 0 for "grant" or "deny," respectively. Three example 
# lookup mechanisms (trivial, flat file, and UNIX password) are provided 
# (choose only one, or place site-specific code here).
# 1. trivial - the next line will return OK for everyone if you uncomment it
#$patron_ok = 1;
# 2. flat file - the next section will lookup a patron ID in a flat file
# containing only IDs (this will likely be the most commonly required option). 
# Replace "/var/tmp/rpademo" with the filename on the library's system.
if (!open(PIDFILE,"/var/tmp/rpademo")) {
print "Content-type: text/plain\n";
print "Status: 454 Error reading ID file\n\nCould not read file\n"; exit;
}
while (<PIDFILE>) {
last if $patron_ok=/^$patron_quoted$/o;
}
close(PIDFILE);
# 3. UNIX passwd file - the next 2 lines will lookup the patron ID in the 
# UNIX /etc/passwd file
#$pwent = getpwnam($patron_quoted);
#$patron_ok = defined($pwent);
# *** Reply section
#
# This section sends the reply back to IAC and generally should not be
# changed in the field. the "$patron_ok" variable determines which answer # is sent.
#
# Status code is the only significant piece of the reply at this time.
# note that the original document said to return "404 Not Found" in case 
# a patron-ID is not valid; "253" is preferred to eliminate ambiguity in 
# the meaning of "404"
print "Content-type: text/plain\n";
if ($patron_ok) {
print "Status: 200\n\n";
print "Authentication successful, access granted for $patron_id\n";
} else {
print "Status: 253\n\n";
print "$patron_id is an unknown patron ID, access denied\n";
}
exit;
sub decodeURL {
$_ = shift;
tr/+/ /;
s/%(..)/pack('c', hex($1))/eg;
return($_);
}