Author image Peter Billam

NAME

CGI::Htauth.pm - Authentication services for CGI scripts.

SYNOPSIS

        use CGI;              # Sadly, CGI::Minimal is not enough
        use CGI::FormBuilder; # usually; Htauth will use it anyway
        use CGI::Htauth;      # :-)

        my $CGI = new CGI;    # necessary when using Htauth
        &initialise_htauth($CGI);  # before any text gets output !

        &header($CGI->param('maintask') || $ENV{SCRIPT_NAME});

        &authenticate(<<EOT);
        dbdir /var/run/htauth
        allow 127.0.0.1                   # trust localhost logins
        deny 10.0.123.*                   # lock out Sales PCs
        password 10.*.*.* timeout=900     # password login on local net
        challenge 123.234.*.* timeout=600 # for Sydney office
        challenge *.*.*.* timeout=0       # just useable for travellers
        EOT

        if ($AUTH_USER eq 'fred') {
          # fred has logged in by password or challenge-response ...
          my $form = CGI::FormBuilder->new(
            params => $CGI,   # necessary when also using Htauth !
            keepextras => 1,  # necessary when also using Htauth !
            method => 'POST', # necessary when also using Htauth !
            fields => [qw(thisfield thatfield theotherfield email)],
            validate => {email => 'EMAIL'},
          );
          if (!$form->submitted || !$form->validate) {
            &output($form->render);  # Must use output not print !
            &footer();
          }
          &do_fred_stuff();
        } else {
          &do_other_stuff();
        }

        sub header {
          output "<HTML><HEAD><TITLE>$_[$[]</TITLE></HEAD><BODY>\n";
        }
        sub footer {
          output "<HR></BODY></HTML>\n";
        }

DESCRIPTION

This Perl library provides authentication services useable by CGI scripts. Several levels of authentication can be imposed, depending on the IP address or hostname of the client.

Then authentication is performed by calling the subroutine authenticate according to a configuration specified its argument.

The calling program must unfailingly use output instead of the usual print so that Htauth can encrypt the HTML text if necessary. The calling program must also call &initialise_htauth($CGI); before any text is output, so that Htauth knows whether to print the text immediately or to save it up for later encryption. If the calling program uses CGI::FormBuilder, the options "params => $CGI", "keepextras => 1" and method => 'POST' must always be present. It is not essential, but will make presentation slicker, if the calling program has subroutines (in package main) called &header($title) and &footer to output (using output, remember...) the HTML header and footer.

CGI::Htauth.pm uses CGI.pm (CGI::Minimal.pm lacks the delete method), uses Crypt::Tea.pm in order to communicate securely with JavaScript-capable browsers, and uses CGI::FormBuilder.pm to manage the data entry. Very often the cgi programmer will be using CGI::FormBuilder.pm anyway, to write the application.

Version 1.21, #COMMENT#

SUBROUTINES

initialise_htauth( $CGI );

The argument $CGI is a reference to a CGI object. This must be called before any text is output to inform Htauth of the state of the parameters.

authenticate( $config_txt, $CGI );

The argument $config_txt is either a multiline text string, or the name of a file containing such a string. IP addresses (indicated as IPADDR) may contain * which matches any string of up to three digits. The second argument is again the reference to the CGI object.

The first config line that matches the client IP address $ENV{REMOTE_ADDR} will determine the type of authentication to which the client is subject. If the user has logged in, either by password or by challenge-response, then the (exported) Perl variable $AUTH_USER is set to the username.

allow IPADDR

Access will be allowed from any IP address matching the $ip pattern.

deny IPADDR

Access will be denied from any IP address matching the $ip pattern.

password IPADDR timestamp=1800

Access from any IP address matching the $ip pattern is met with a Username-and-Password login request. This data travels over the network in cleartext (unless you are using https). If the Password is valid, then a temporary session key is generated, which is passed back to the next invocation by hidden form variables.

This routine uses various FORM variables beginning with htauth_ and applications would be wise to avoid creating FORM variables beginning with htauth_ as these may produce Unpredictable Consequences.

challenge IPADDR timestamp=0

Access from any IP address matching the $ip pattern is met with a Username request and a One-time-key challenge. This data travels over the network in cleartext (unless you are using https). If the Password is valid, then a temporary session key is generated, which is passed back to the next invocation by hidden form variables. A new temporary session key is generated every invocation, so the user will not be able to use the browser's Back key.

If the session is within 30 seconds of timing out, a new One-time-key challenge is issued instead. Thus setting the timeout to less than 30 seconds (e.g. to 0, the default) causes a One-time-key challenge to be issued on every page.

This routine uses various FORM variables beginning with htauth_ and applications would be wise to avoid creating FORM variables beginning with htauth_ as these may produce Unpredictable Consequences.

set_password ( $dbdir, $username, $password );

The argument $dbdir is the directory in which the password databases will be set up. If it doesn't exist, it should be createable. It must be writeable by the httpd user, eg nobody or wwwrun.

The argument $username is the Htauth-username whose password is to be changed. This username will be created if it doesn't yet exist.

The argument $password is the new password.

RESERVED WORDS

Like everything on the web, CGI::Htauth.pm must do its stuff by manipulating frames, forms and query variables. The names it reserves for its own use all begin with htauth_ so applications should avoid creating frames, forms, query variables or JavaScript variables or methods beginning with htauth_ as these may have Unpredictable Consequences.

htauth_frame0

is the almost invisible top frame which occurs in JavaScript login; it contains nothing but the hidden forms htauth_form0 (to submit), htauth_form1 (to log in again) and htauth_form2 (to log out)

htauth_frame1

is the main frame which occurs in JavaScript login; it contains the application as seen by the user.

htauth_form0

is the hidden form which is filled out by JavaScript with the encrypted data htauth_t and the response htauth_r, and is really submitted when the user thinks they're submitting the application form visible in htauth_frame1. This form is also used, with htauth_x = change, to change password.

htauth_form1

is the hidden form with a TARGET of the main (parent) FRAMESET, which causes Htauth to ask for a new login.

htauth_form2

is the hidden form with a TARGET of the main (parent) FRAMESET, which logs the user out and restarts the entire script with no variables.

htauth_form4

is the form used during non-JavaScript login which asks for username and password.

htauth_form5

is the form in htauth_frame1 which just asks for username, used during login on a JavaScript-capable browser; it also sniffs to see is JavaScript is enabled.

htauth_j

is a sniffer variable, which the browser sets to 'yes' if JavaScript is actually enabled.

htauth_form6

is the form which just asks for password, residing in htauth_frame1 and used during password login on a JavaScript-enabled browser

htauth_u is the htauth Username
htauth_p

is a Password as entered by user; it only gets transmitted to the server if the user does not have a JavaScript-enabled browser.

htauth_c

is the challenge issued by the server during the JavaScript password login dialogue.

htauth_k

is a Session Key, generated at login by Htauth, which is used during a login session.

htauth_r

is the browser's Response to a challenge by the server; it is used both during challenge-response login, and during the JavaScript password login dialogue.

htauth_t

is stuff encrypted by Crypt::Tea in the browser

htauth_x

is a hold-all for other commands such as change password, log out, etc etc

htauth_bg

is used during a JavaScript login session; it is set to the document BGCOLOR by JavaScript in the browser, and is used by Htauth to set a background colour for all its dialogue which fits the decor of the application.

htauth_fg

is likewise set to the document TEXT by JavaScript in the browser, and is used by Htauth to set a foreground colour for its dialogues.

FUTURE DEVELOPMENTS

Currently challenge-response is not really implemented.

Several more config directives are tempting, for example: some built-in way of insisting on a minimum password length, logdir to allow logging of logins and logouts, perhaps other modes to specify use of Crypt::Tea during login for security but then an unencrypted session to lighten the CPU load on the server, or to allow only JavaScript browsers so that the password can never be betrayed.

Perhaps for a session, the challenge could be used together with the password as the encryption key, to make cryptanalyisis harder for someone prepared to sniff multiple login sessions.

User admin functions could be much more pre-packaged and complete.

AUTHOR

Peter J Billam <computing@pjb.com.au>

CREDITS

Based on and older module called htauth.pm which used htui.pm to handle the user interface, instead of Nathan Wiger's CGI::FormBuilder.pm. Thanks also to Neil Watkiss for MakeMaker packaging.

SEE ALSO

http://www.cpan.org/SITES.html, http://www.pjb.com.au/, CGI.pm, CGI::FormBuilder.pm, Crypt::Tea.pm, perl(1).

1 POD Error

The following errors were encountered while parsing the POD:

Around line 1103:

You forgot a '=back' before '=head1'