Apache-SecSess

 view release on metacpan or  search on metacpan

INSTALL  view on Meta::CPAN

THEN AS ROOT,

	cd db; cp dbilogin.txt /usr/local/apache/conf/private

NOTE: This path is hard-coded in startup.pl, so if you change it, you must
change it consistently everywhere.


5. Set up IP Aliasing.

The demo shows the transfer of credentials between different hosts.  You
don't actually need separate physical hosts, if your machine supports IP 
aliasing.

On Linux, if you have an old kernel (<2.4?) read the HOWTO on IP Aliasing.  
Otherwise (new linux kernels), ip aliasing is automatic.  Here is the 
relevant fragment from my /etc/hosts:

	## prototype web devel virtual hosts (some Libertarians)
	192.168.1.11	adam.acme.com adam smith
	192.168.1.12	lysander.acme.com lysander spooner

INSTALL  view on Meta::CPAN


7. Try the demos.

All relevant user login info is:

	user: bob
	password: sekret
	pin code: 0918

As you go from top to bottom in the menu, there are increasing
authentication requirements, and increasingly strong credentials are
issued.  When you get to milt.sec.acme.com, watch carefully, as you will 
be redirected to stu.transacme.com for login.  And, when stu issues
URL credentials you will be transparently redirected across domains to get
cookies for milt.sec.acme.com and noam.acme.org, before being redirected
back to the original milt request.  Then you may hop to noam and stu 
without further interruption.

README  view on Meta::CPAN

./rfc/*.txt                     Related IETF RFC's describing cookies.
./COPYING,./LICENSE             Copyright and license info.


1.  What Problems are We Trying to Solve?
-----------------------------------------

Problem 1: No Secure Single Sign-On.

There is not as far as we know, an Apache module which will securely transfer 
credentials from a login on one trusted host to multiple cooperating hosts, 
across multiple DNS domains and across a range of SSL capabilities.

Problem 2: HTTP Cookie Weaknesses.

Not implicit from problem (1), is the subtle fact that considerable
care must be taken to securely share credentials within a single DNS
domain using HTTP state management (aka Netscape Cookies) as described
in [RFC2109] and [RFC2965].  In fact, the traps and pitfalls are so numerous 
that [RFC2964] generally forbids the use of cookies for any kind of security 
authentication.
  One way to look at this package is as a very simple cryptographic 
protocol designed to defend against attacks which exploit known cookie 
vulnerabilities.


2.  Summary of Features
-----------------------

   * Secure sharing of multi-level credentials within and across DNS domains.
   * Support for different representations of credentials with the ability to 
     chain and interoperate between them.
   * Built-in defense against on-line guessing attacks.
   * Built-in session timeout, both idle and hard-limit.
   * Built-in SU-type function for admins to switch user ID's.
   * Encapsulated database interface.


3.  Known Security Issues with HTTP Cookies
-------------------------------------------

README  view on Meta::CPAN

cookie to a user who can then request resources from wendel.  Even
if you don't admit either passive or active adversaries on the network, the 
user's identity might still be compromised.  If hopkins.acme.com is
compromised and the user visits *any* other compromised site, say
www.fantasyland.org, a trojan .html document with a malicious image
tag <img src="http://hopkins.acme.com">, will send the identity cookies 
directly to hopkins who is waiting for them.  (This is the old 3rd-party
cookie bugaboo exploited by *click.com.)

Solution: Regardless of the mechanism used for representing user 
credentials (cookies, URL's, etc), there will be some set of hosts
included in the system (whether spanned by wildcard matches or server
side redirects).  No untrusted host should be in that set.  This is 
just classic host security.


Issue 3:  Secure Wildcard Cookies Don't Always Have Intended Protection

The underlying weakness in issue (2) is perhaps more relevant for so-called 
secure cookies (with secure flag is set).  Even where host security can be 
assumed across a large heterogeneous environment, there might be one
host which only supports 40-bit SSL, say hopkins.acme.org again.  Supposed 
bruce and wendel were properly configured for only 128-bit cipher suites 
and issued only secure cookies for the .acme.com domain.  Then a malicious 
image tag <img src="https://hopkins.acme.com"> will force a connection
to hopkins.  If 40-bit encryption is negotiated (see next issue), the user's
credentials are reduced from 128-bits to 40-bits.
   Unlike issue (2), we cannot pass this off as a matter of host security, 
because hopkins is not compromised.  A passive adversary who obtains
a 40-bit encrypted copy of the credentials.  He can then do an offline crack 
in order to assume the users identity.  Naively, bruce and wendel might
think an implausible work factor of 2^128 would be necessary.

Solution: A cookie-based authentication module must be configurable
to treat a wildcard .acme.com domain as essentially weak.  Cookies
used for strong authentication must be either confined to a single
host, or to a more restrictive wildcard like '.secure.acme.com'.  The 
demo software shows examples of both.


README  view on Meta::CPAN

-------------------------

5.1  The Authentication Processes
---------------------------------

There are three notions of 'authentication' in Apache::SecSess.

    User Authentication: This serves to identify the user and to provide
        a suitable proof of that identity.  This is typically a login form,
        which interrupts the user, but it might transparently use other 
        credentials which are already available electronically like an X.509
        client certificate or a persistent cookie.

    Session Authentication: This is Apache's notion of authentication as
        carried out by PerlAuthenHandler.  Here, an actual resource, like an 
        HTML doc, will be delivered if all is successful.

    Chaining Authentication:  In this type of authentication, credentials
        suitable for session authentication are interpreted instead as user
        authentication in order to issue another type of credential.  In the 
        demo for example, single sign-on across DNS domains is accomplished 
        by double chaining.  Local cookies are used to the identify user and 
        issue URL credentials during a redirect across the domain, where
        the URL credentials are used to identify/authenticate the user again
        in order to issue cookies within the *new* domain.


5.2  The Security Mechanism
---------------------------

The fundamental security mechanism of Apache::SecSess is the issuance
of simple cryptographic proofs of identity explicitly constructed to
return to the system's various servers via HTTP(S) sessions which are 
protected with sufficient strength, despite the malicious behavior by an 
adversary.  This is achieved in a rather mundane way, namely by avoiding
all the pitfalls of the enumerated issues in Sect. 3.  

In the case of URL credentials, the current implementation requires all
URL's to be explicitly configured.  All redirects are automatic, occurring
under SSL of a specified strength.  There should be no surprises here; if
URL credentials were stolen, the adversary would have had to crack one of
a small number of SSL connections under the complete control of the security 
administrator.

In the case of Cookie credentials, *multiple* cookies are issued, one for 
each anticipated security level.  For example, a user who logs in with an 
X.509 client certificate might be issued 3 cookies: one cleartext cookie 
intended for non-sensitive data, one SSL (secure flag) cookie broadly 
distributed to .acme.com with 40-bit crypto possible, and finally one SSL 
cookie intended only for the 128-bit originating host.  An adversary who 
manages to steal either the cleartext or the 40-bit cookie cannot use it to 
acquire 128-bit level resources, because the cookies themselves have 
unforgeable assertions of security level which are checked during session 
authentication as described in the next section.

README  view on Meta::CPAN

Credentials in Apache::SecSess have a similar format:

    URL Credentials:
        realm=E_k(md5(hash),hash)

    Cookie Credentials: 
        realm:qop,authqop=E_k(md5(hash),hash)

(The only difference is that the quality of protection parameters 
discussed below, qop and authqop, are repeated in the clear for cookie
credentials in order to ease processing.)

The string 'realm' is any symbol (without obvious special characters 
':', '=', etc) which is used to identify cooperating security services,
thus providing a way to put credentials into their own namespace.

The 'hash' is a string representation of a Perl hash of the form:

    hash = {
        uid => string: user ID
        timestamp => integer: time stamp from time(),
        qop => integer: session quality of protection,
        authqop => integer: user authentication quality of protection
    }

See the source code of Wrapper.pm for details of how the hash is converted 
into a string.

The encryption function E_k is currently not very configurable.  It is 
Rijndael (AES) in CBC mode with IV=0.  It is well known that CBC mode is 
vulnerable to forgeries, so a cryptographic checksum is prepended to the 
plaintext, as indicated.  

The secret key k must be shared by all host or web servers which use the same
realm.  Without the secret key, it should be cryptographically infeasible to 
produce credentials in which the hash and checksum match.  It should 
therefore be cryptographically infeasible for anyone to forge credentials or 
alter them in any way.


References
----------

[RFC2109] D. Kristol, L. Montulli, HTTP State Management Mechanism, 
    RFC 2109, 1997.

[RFC2964] K. Moore and N. Freed, Use of HTTP State Management

SecSess.pm  view on Meta::CPAN

	if (ref($resp)) {
		if ($msg = $resp->{message}) { $log->info($msg); }
		if ($resp->{forbidden}) { return FORBIDDEN; }
		unless ($resp->{uri}) { return SERVER_ERROR; }
		$r->header_out(Location => $resp->{uri});
		return REDIRECT;
	}
	return DECLINED;
}

## authenticate user & issue credentials
sub issue ($$) {
	my($self, $r) = @_;
	my $log = $r->log;
	my($resp, $msg);

	## don't perform in subrequests
	unless ($r->is_initial_req) { return OK; }

	$log->debug(ref($self), "->issue():");

SecSess.pm  view on Meta::CPAN

		return REDIRECT;
	}
	$resp = $self->issueCredentials($r);
	unless (ref($resp)) { $log->error($resp); return SERVER_ERROR; } 
	if ($msg = $resp->{message}) { $log->info($msg); }
	unless ($resp->{uri}) { return SERVER_ERROR; }
	$r->header_out(Location => $resp->{uri});
	return REDIRECT;
}

## renew credentials
sub renew ($$) {
	my($self, $r) = @_;
	my $log = $r->log;
	my($cred, $resp, $msg);

	## don't perform in subrequests
	unless ($r->is_initial_req) { return OK; }

	$log->debug(ref($self), "->renew():");

	$cred = $self->getCredentials($r);
	$resp = $self->validateCredentials($r, $cred);
	unless (ref($resp)) { $log->error($resp); return SERVER_ERROR; } 
	unless ($resp->{renew}) { # make sure credentials are sufficiently fresh
		$log->warn("Timeout before renewal."); # or replay attempt?
		if ($msg = $resp->{message}) { $log->info($msg); }
		unless ($resp->{uri}) { return SERVER_ERROR; }
		$r->header_out(Location => $resp->{uri});
		return REDIRECT;
	}
	$resp = $self->issueCredentials($r);
	unless (ref($resp)) { $log->error($resp); return SERVER_ERROR; } 
	if ($msg = $resp->{message}) { $log->info($msg); }
	unless ($resp->{uri}) { return SERVER_ERROR; }
	$r->header_out(Location => $resp->{uri});
	return REDIRECT;
}

## delete credentials
sub delete ($$) {
	my($self, $r) = @_;
	my $log = $r->log;
	my($resp, $msg);

	## don't perform in subrequests
	unless ($r->is_initial_req) { return OK; }

	$log->debug(ref($self), "->delete():");

SecSess.pm  view on Meta::CPAN

	unless ($r->is_initial_req) { return OK; }

	$log->debug(ref($self), "->changeid():");

	## admin functions must be explicitly allowed in httpd.conf
	unless ($r->dir_config('SecSess::AllowRemoteAdmin') eq 'true') { 
		$log->error('Remote administration not permitted.');
		return FORBIDDEN;
	}

	## get credentials and validate them in usual way
	$cred = $self->getCredentials($r);
	$resp = $self->validateCredentials($r, $cred);
	if (ref($resp)) {
		if ($msg = $resp->{message}) { $log->info($msg); }
		unless ($resp->{uri}) { return SERVER_ERROR; }
		$r->header_out(Location => $resp->{uri});
		return REDIRECT;
	}

	## make sure request is consistent and comes from an administrator

SecSess.pm  view on Meta::CPAN

	unless (ref($resp)) { $log->error($resp); return SERVER_ERROR; } 
	if ($msg = $resp->{message}) { $log->info($msg); }
	if ($resp->{forbidden}) { return FORBIDDEN; } # non-admin
	if ($resp->{fill_form}) { return OK; }
	unless ($uid = $resp->{newuid}) {
		unless ($uri = $resp->{uri}) { return SERVER_ERROR; }
		$r->header_out(Location => $uri);
		return REDIRECT;
	}

	## every looks good, set uid and issue new credentials
	$r->user($uid);
	$resp = $self->issueCredentials($r);
	unless (ref($resp)) { $log->error($resp); return SERVER_ERROR; } 
	if ($msg = $resp->{message}) { $log->info($msg); }
	unless ($resp->{uri}) { return SERVER_ERROR; }
	$r->header_out(Location => $resp->{uri});
	return REDIRECT;
}

#

SecSess.pm  view on Meta::CPAN

sub issueURL { my $self = shift; return $self->{issueURL}; }
sub chainURLS { my $self = shift; return $self->{chainURLS}; }

## admin form
sub adminURL { my $self = shift; return $self->{adminURL}; }

#
# routines
#

## validate common hash credentials from
sub validateCredentials {
	my $self = shift;
	my($r, $cred) = @_;
	my $log = $r->log;
	my($uri, $requri, $resp, $uid);

    $log->debug(ref($self), "->validateCredentials():");

	## were illegitimate credentials found?
	unless (defined($cred)) { # probably a key-change, treat as timeout
		# but possibly tampering, so log as warning
		$log->warn("Decryption Error");
		$uri = $self->timeoutURL;
		return {
			message => "Decryption failure, redirecting to '$uri'.",
			uri => "$uri?type=notvalid"
		};
	}

	## were any credentials found at all?
	unless (ref($cred)) {
		$uri =  sprintf('%s?url=%s',
			$self->authenURL,
			$self->requested_uri($r)
		);
		return {
			message => "$cred Redirecting to '$uri'",
			uri => $uri
		};
	}

SecSess.pm  view on Meta::CPAN

		$uri = $self->timeoutURL;
		return {
			message => "Cookie idle too long '$uid'.",
			uri => "$uri?type=idle"
		};
	}
	if ($t > $ts + 60*$renew) { # renew
		$uri = $self->renewURL;
		$requri = $self->requested_uri($r);
		return {
			message => "Renewing credentials for user '$uid'.",
			renew => 'true',
			uri => "$uri?url=$requri"
		};
	}

	return undef;
}

## get requirements
sub getRequirements {

SecSess.pm  view on Meta::CPAN

   `+-Cookie
    | `+--BasicAuth (for debugging)
    |  +--LoginForm
    |  +--X509
    |  +--X509PIN
    |  `--URL
    `-URL
      `---Cookie

SecSess contains (in addition to common code) all Apache phase handlers
(Currently only  PerlAuthenHandler are needed).  At this level credentials
and status are considered opaque objects. The important methods are:

->authen() Used to protect underlying resources.  Checks credentials for freshness and validity.

->issue()  Used as the "initial" identity authentication before issuing credentials (cookies or mangled URLs) used by ->authen().

->renew()  Will re-issue credentials if proper conditions are satisfied

->delete() Will delete credentials where relevant (i.e. deletes cookies).

At one level beneath SecSess (SecSess::Cookie.pm and SecSess::URL.pm),
are the methods for interpreting and manipulating credentials.

At the lowest level, are subclasses which "know" how to interpret the
*initial* identifying information during the issuance of credentials.
So, *::Cookie::LoginForm presents the client with a user/password
login form for identification.  And thus the difference between 
*::Cookie::URL and *::URL::Cookie is that the former will issue cookies
after validating an URL credential, and the latter will "issue" an URL
credential (typically it will redirect to a resource with realm=cred in
the URL) after validating a cookie.

=head1 CREDENTIAL FORMAT

Credentials in Apache::SecSess have a similar format:

    URL Credentials (defined in Apache::SecSess::URL):
        realm=E_k(md5(hash),hash)

    Cookie Credentials: (defined in Apache::SecSess::Cookie):
        realm:qop,authqop=E_k(md5(hash),hash)

The string 'realm' is any symbol (without obvious special characters 
':', '=', etc) which is used to identify cooperating security services,
thus providing a way to put credentials into their own namespace.
The 'hash' is a string representation of a Perl hash of the form:

    hash = {uid => str, timestamp => int, qop => int, authqop => int}

See README and Wrapper.pm for further details.

=head1 ARGUMENTS

=head2 Credential Arguments

  authRealm => <realm>

Defines string 'realm' as identifying tag for credentials as described
above in CREDENTIAL FORMAT.

  secretFile => <filename>

The first line of this file is used to create the secret encryption 
key for credentials as described above in CREDENTIAL FORMAT.  This
secret key is never given to users and should never leave the system
servers.

=head2 Timing Arguments

  lifeTime => <minutes>

Session will expire after the specified number of minutes.

  idleTime => <minutes> 

SecSess.pm  view on Meta::CPAN

  renewRate => <minutes>

A session which is constantly active will have a transparent
renewal (resetting an implicit 'idle timer') every period of the 
specified number of minutes.

=head2 Quality of Protection Arguments

minSessQOP => 128, minAuthQOP => 128, authQOP => 128, sessQOP => 128

When credentials are validated during a request, two checks of the 
qualities of protection (QOP's) are made, namely that

        qop >= minSessQOP
and 
        authqop >= minAuthQOP

where qop and authqop indicate the session and user authentication 
protection or strength roughly measured in bits.  They are the signed 
values appearing *inside* the credential hash described above.  In the 
case of cookies, where multiple credentials with different security 
levels are may be present at request time, only the strongest credentials 
are used to make this determination.  (The cleartext pairs (qop,authqop) 
are sorted lexicographically to determine which cookies to use.  The
cleartext values are not trusted.)
  
The QOP parameters are separated to allow flexibility in the threat model.
In the simplest paradigm (and first demo examples), qop=0 and authqop=40, 
which merely indicates that the user ID's and passwords are protected with 
SSL but the web docs acquired with them are not.  This is somewhat common 
over intranets.  Under the stronger threat model of an active adversary
who controls the untrusted network, true end-to-end security is 
required, but we may still wish to separate session and authentication 
qualities of protection.  For example, if all SSL sessions never drop
below 128-bits, we may still choose to allow weaker strength during user 
authentication, say with a 20-bit PIN or one-time password.  Scientific 
cryptography cannot always afford to distinguish between an attack which 
costs 2^20 computations and one which succeeds with probability 1/2^20, 
because with 1 million users, the two situations are identical.  But, for
practical risk assessment, it may be perfectly acceptable to trade strong
session credentials for weak login credentials.

The values of qop and authqop issued are determined by the
Apache::SecSess object in all cases.  For URL credentials they come
directly from arguments sessQOP and authQOP, respectively.  For cookie
credentials, they come from the hash keys of the argument cookieDomain
described below.
 
Note that no attempt is made to check the correctness of the QOP
settings against the values of the httpd.conf directive SSLCipherSuite.
This would be mistake in fact because the session strength is dependent
on global factors as described in README.  Nevertheless, you should 
check your assumptions about your local site's openssl with the script 
utils/minstren which prints the weakest cipher strength for common 
SSLCipherSuite arguments.  At my site, I was surprised to find 
ALL:!ADH:!EXP:!EXP56 => 56 bits.

SecSess.pm  view on Meta::CPAN

wildcard domains, *.acme.com supporting any export crippled, SSLv2
host, and *.sec.acme.com which intended to have a minimum of 64 bits 
throughout.

=head2 Session State URL Arguments

These have the obvious meaning and must agree in host, scheme, and
path with the corresponding Apache directives, as shown in the EXAMPLE 
section.  Generally for example,

authenURL => Where to go to get the appropriate credentials for a requested 
resource.

defaultURL => Where to go after logging in (if no initial request was made).

timeoutURL => Where to go to delete credentials.  Timeouts  and signouts 
are both sent here.

=head2 URL Chaining Arguments

  chainURLS => <arrayref>, issueURL => <string>

Apache::SecSess is designed to use cookies for most local authentication.  By 
their definition, cookies are restricted to a host, a DNS domain or subdomain.
The subclass Apache::SecSess::URL, which allows you to span authentication 
across DNS domains, requires additional arguments to accomplish this.   The 
argument chainURLS expects an array reference which defines a list of places 
to go for more (typically cookie) credentials.  For example,

      chainURLS => [
        'https://milt.sec.acme.com/authen', 
        'https://noam.acme.org/authen'
      ]

says that when URL credentials are issued, the client will be redirected
to each of the specified sites, in turn.  Each of these is expected to
be protected by a PerlAuthenHandler of type Apache::SecSess::Cookie::URL, 
which will issue local cookies.

The argument issueURL is used to tell the remote sites (listed in chainURLS 
arg) where to redirect the client back to, in order to continue chaining.

See the URL-Chaining example and the demo for more details.

=head2 Database Object Argument

SecSess.pm  view on Meta::CPAN

          128 => 'tom.acme.com'
      },
      minSessQOP => 128, minAuthQOP => 128, 
      authenURL => 'https://tom.acme.com/authen',
      defaultURL => 'https://tom.acme.com/protected',
      renewURL => 'https://tom.acme.com/renew',
      timeoutURL => 'https://tom.acme.com/signout/timeout.html',
      errorURL => 'http://tom.acme.com/error.html'
  );

Now, on the host which issues credentials, (tom.acme.com in this example),
add the following additional Apache directives to http.conf:

  ## issues cookies
  <Location /authen>
    SetHandler perl-script
    AuthName "Adam Realm"
    AuthType Basic
    PerlAuthenHandler $Acme::obj->issue
    require valid-user
  </Location>

SecSess/Cookie.pm  view on Meta::CPAN

		my($bs, $ba) = split(',', $b);
		return ($bs <=> $as) ? ($bs <=> $as) : ($ba <=> $aa);
	} (keys %ckys);
	$max = $tags[0];
	unless (defined($max)) { return 'No cookie found.'; }
	$log->debug(sprintf("Found Cookie: %s:%s=%s", $realm, $max, $ckys{$max}));

	return $self->{wrapper}->unwraphash($ckys{$max});
}

## validate (usually non-cookie) credentials used to authenicate user
sub verifyIdentity { my $self = shift; return undef }

## issue cookies
sub issueCredentials {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my(@cky, %args, $url);

	$log->debug(ref($self), "->issueCredentials():");

	## put credentials into headers
	for (@cky = $self->setCookies($r)) {
		$r->err_headers_out->add('Set-Cookie' => $_);
	}

	## form target URL and response
	%args = $r->args;
	$url = $self->unwrap_uri($args{url}) || $self->defaultURL;
	$log->debug("redirect url (after cookies) = ", $url, " args{url}: ", 
		$args{url});
	unless ($url) { return 'No place to go (no defaultURL set).'; }

SecSess/Cookie/BasicAuth.pm  view on Meta::CPAN


use Apache::Constants qw(:common :response);
use Apache::SecSess::Cookie;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess::Cookie);

## validate (usually non-cookie) credentials used to authenicate user
sub verifyIdentity {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my($uid, $res, $pw, $msg);

    $log->debug(ref($self), "->verifyIdentity():");

	## read password and user id if present, bail otherwise
	($res, $pw) = $r->get_basic_auth_pw;

SecSess/Cookie/LoginForm.pm  view on Meta::CPAN

use strict;

use Apache::SecSess::Cookie;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess::Cookie);

## validate (usually non-cookie) credentials used to authenicate user
sub verifyIdentity {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my(%params, $uid, $pw, %args, $url, $form, $msg);

    $log->debug(ref($self), "->verifyIdentity():");

	## is this the initial visit to the form?
	unless ($r->method eq 'POST') { # allow no GET for now ...

SecSess/Cookie/URL.pm  view on Meta::CPAN


use Apache::SecSess::Cookie;
use Apache::SecSess::Wrapper;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess::Cookie);

## validate (usually non-cookie) credentials used to authenicate user
sub verifyIdentity {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my(%args, $ctxt, $urlcred);

    $log->debug(ref($self), "->verifyIdentity():");

	## extract ciphertext from URL
	%args = $r->args;
	$ctxt = $args{$self->authRealm};
	$urlcred = $self->{wrapper}->unwraphash($ctxt);

	## validate URL credentials as we would at higher level
	return $self->validateCredentials($r, $urlcred);
}

1;

__END__
What are you looking at?

SecSess/Cookie/X509.pm  view on Meta::CPAN

use strict;

use Apache::SecSess::Cookie;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess::Cookie);

## validate (usually non-cookie) credentials used to authenicate user
sub verifyIdentity {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my($subr, $email, $uid);

    $log->debug(ref($self), "->verifyIdentity():");

	## resolve user ID from certificate DN email
	$subr = $r->lookup_uri($r->uri);

SecSess/Cookie/X509PIN.pm  view on Meta::CPAN

use strict;

use Apache::SecSess::Cookie;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess::Cookie);

## validate (usually non-cookie) credentials used to authenicate user
sub verifyIdentity {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my($subr, $email, $uid, %params, $pin, %args, $url, $form, $msg);

    $log->debug(ref($self), "->verifyIdentity():");

	## resolve user ID from certificate DN email
	$subr = $r->lookup_uri($r->uri);

SecSess/URL.pm  view on Meta::CPAN

use Apache::Constants qw(:common :response);
use Apache::SecSess;
use Apache::SecSess::Wrapper;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess);

## extract appropriate credentials from headers and decrypt contents
sub getCredentials {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my(%args, $ctxt);

    $log->debug(ref($self), "->verifyIdentity():");

	## extract ciphertext from URL
	%args = $r->args;
	$ctxt = $args{$self->authRealm};
	unless ($ctxt) { return 'No URL credentials found.'; }

	return $self->{wrapper}->unwraphash($ctxt);
}

## validate (usually non-url) credentials used to authenicate user
sub verifyIdentity { my $self = shift; return undef }

## issue credentials
sub issueCredentials {
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my($uid, $realm, $ctxt, %args, $requrl, $idx, @chains, $chain, $url, $sep);
	my($backurl);

	$log->debug(ref($self), "->issueCredentials():");

	## form credentials as URL query string fragments
	$uid = $r->user;
	$realm = $self->authRealm;
	$ctxt = $self->{wrapper}->wraphash({
		uid => $uid,
		timestamp => time,
		qop => $self->sessQOP,
		authqop => $self->authQOP
	});

	## determine whether in (multi-host) chaining mode

SecSess/URL.pm  view on Meta::CPAN

			};
		}
		else { # done chaining
			return {
				message => "Redirecting '$uid' to original '$requrl'.",
				uri => $requrl
			};
		}
	}

	## non-chaining mode, tack credentials onto original url and redirect
	$sep = ($requrl =~ /\?/) ? '&' : '?';
	$requrl .= sprintf('%s%s=%s', $sep, $realm, $ctxt);
	return {
		message => "Redirecting '$uid' to '$requrl'.", 
		uri => $requrl
	};
}

## delete - nothing to delete
sub deleteCredentials { }

SecSess/URL/Cookie.pm  view on Meta::CPAN

use Apache::SecSess;
use Apache::SecSess::URL;
use Apache::SecSess::Wrapper;

use vars qw(@ISA $VERSION);

$VERSION = sprintf("%d.%02d", (q$Name: SecSess_Release_0_09 $ =~ /\d+/g));

@ISA = qw(Apache::SecSess::URL);

## validate credentials used to first authenicate user
sub verifyIdentity { 
	my $self = shift;
	my($r) = @_;
	my $log = $r->log;
	my($realm, $ckyhead, %ckys, @tags, $max, $url, $ckycred);

    $log->debug(ref($self), "->verifyIdentity():");

	## extract strongest cookie with appropriate name/tag pair
	$realm = $self->authRealm;

demo/ht/adam.acme.com/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/ht/john.sec.acme.com/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/ht/lysander.acme.com/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/ht/milt.sec.acme.com/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/ht/noam.acme.org/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/ht/stu.transacme.com/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/ht/tom.acme.com/signout/timeout.html  view on Meta::CPAN

<& /index.comp, title => 'Session Timeout', content => $content &>

<%init>
my %messages = (
	idle => 
	'<b>Idle Timeout:</b> your session remained inactive for too long.',
	expire => 
	'<b>Expiration:</b> your session has expired.',
	notvalid => 
	'<b>No Longer Valid:</b> your session credentials are no longer valid.',
	unknown => 
	'<b>Unknown Reason.</b>'
);

my $content = <<"ENDCONTENT";
<font color="#f42424" size=5>Session Timeout.</font><p>
Your login session has timed out due to the following reason:
<ul>
	<li> $messages{$type}
</ul>

demo/httpdconf/startup.pl  view on Meta::CPAN

	authRealm => 'Acme',
	cookieDomain => { 128 => 'stu.transacme.com' },
	authenURL => 'https://stu.transacme.com/authen',
	defaultURL => 'https://stu.transacme.com/chain',
	renewURL => 'https://stu.transacme.com/renew',
	timeoutURL => 'https://stu.transacme.com/signout/timeout.html',
	adminURL => 'https://stu.transacme.com/changeid',
	errorURL => 'http://stu.transacme.com/error.html'
);

## stu.transacme.com issue mangled-URL credentials based on stu cookies
$Acme::chain = Apache::SecSess::URL::Cookie->new(
	dbo => Apache::SecSess::DBI->new(
		dbifile => '/usr/local/apache/conf/private/dbilogin.txt'
	),
	secretFile => '/usr/local/apache/conf/private/ckysec.txt',
	lifeTime => 1440, idleTime => 60, renewRate => 5,
	sessQOP => 128, authQOP => 128,
	minSessQOP => 128, minAuthQOP => 128,
	authRealm => 'Acme',
	authenURL => 'https://stu.transacme.com/authen',

rfc/rfc2964.txt  view on Meta::CPAN

   Because such practices encourage users to defeat HTTP State
   Management mechanisms, they tend to reduce the effectiveness of HTTP
   State Management, and are therefore considered detrimental to the
   operation of the web.

2.2.2.  Use as an Authentication Mechanism

   It is generally inappropriate to use the HTTP State Management
   protocol as an authentication mechanism.  HTTP State Management is
   not designed with such use in mind, and safeguards for protection of
   authentication credentials are lacking in both the protocol
   specification and in widely deployed HTTP clients and servers.  Most
   HTTP sessions are not encrypted and "cookies" may therefore be
   exposed to passive eavesdroppers.  Furthermore, HTTP clients and
   servers typically store "cookies" in cleartext with little or no
   protection against exposure.  HTTP State Management therefore SHOULD




Moore & Freed            Best Current Practice                  [Page 4]



( run in 0.381 second using v1.01-cache-2.11-cpan-a5abf4f5562 )