Subject: | Controlling cache from Apache config file; hashing data in cache |
Two wishlist issues here, but I have a patch for both, so I'll do it as
one bug.
First, because the cache parameter to objects which inherit from
Authen::Simple::Adapter is a cache object, it's impossible to configure
it from the Apache config file. One solution is to allow the name of
the cache class to be put in the config file, and when the object is
constructed an object of that class will be created. The attached patch
implements this, with the name "cacheclass". If the class name is
followed by whitespace, the rest of the setting is taken as a
whitespace-seperated list of arguments for the class's constructor.
Second, if the authentication information is sensitive, it is less than
ideal to store it in a plaintext cache which is readable by the Web
server process. It's straightforward to hash the information before
caching it. The patch also adds a "cachehash" option, which is the name
of a digester which will be passed to Digest->new. If it is set,
username/password pairs will be hashed before they are stored in the
cache, and before they are looked for in the cache.
For example, here's what I have in my httpd.conf:
PerlModule Authen::Simple::MyHTTP
PerlSetVar AuthenSimpleMyHTTP_cachehash "SHA-256"
PerlSetVar AuthenSimpleMyHTTP_cacheclass "Cache::FastMmap share_file
/home/www/data/cache/KxAuth.cache"
BTW, the code was very straightforward, extremely easy to modify, and a
delight to work with. Thanks!
Subject: | authen-simple-adapter-sg.patch |
--- Adapter.pm~ 2006-01-13 15:19:55.000000000 -0500
+++ Adapter.pm 2007-04-17 23:21:13.000000000 -0400
@@ -8,10 +8,12 @@
use Authen::Simple::Password qw[];
use Carp qw[];
use Params::Validate qw[];
+use Digest;
__PACKAGE__->mk_classdata( _options => { } );
-__PACKAGE__->mk_accessors( qw[ cache callback log ] );
+__PACKAGE__->mk_accessors( qw[ cache cachehash callback log cacheclass ] );
+our $cacheclass_loaded;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
@@ -32,6 +34,17 @@
$self->$method($value);
}
+ if (!$self->cache && $self->cacheclass) {
+ my($cacheclass,@cacheargs)=split(' ',$self->cacheclass);
+ if (!$cacheclass_loaded) {
+ eval "use $cacheclass;";
+ if ($@) {
+ die "Error including '@{[$self->cacheclass]}': $@";
+ }
+ }
+ $self->cache($cacheclass->new(@cacheargs));
+ }
+
return $self;
}
@@ -69,9 +82,19 @@
}
}
+ my $hash_upw;
+ if ($self->cachehash) {
+ my $hasher = Digest->new($self->cachehash)
+ or die "Couldn't get hasher '@{[$self->cachehash]}'";
+ $hasher->add("$username:$password");
+ $hash_upw = $hasher->b64digest;
+ } else {
+ $hash_upw="$username:$password";
+ }
+
if ( $self->cache ) {
- $status = $self->cache->get("$username:$password");
+ $status = $self->cache->get($hash_upw);
if ( defined $status ) {
@@ -86,7 +109,7 @@
if ( $self->cache && $status ) {
- $self->cache->set( "$username:$password" => $status );
+ $self->cache->set( $hash_upw => $status );
$self->log->debug( qq/Caching successful authentication status '$status' for user '$username'./ )
if $self->log;
@@ -134,6 +157,16 @@
optional => 1
};
+ $options->{cachehash} ||= {
+ type => Params::Validate::SCALAR,
+ optional => 1
+ };
+
+ $options->{cacheclass} ||= {
+ type => Params::Validate::SCALAR,
+ optional => 1
+ };
+
$class->_options($options);
}