On Mon, Jul 07, 2003 at 10:06:59AM -0700, Geoffrey Young wrote:
[...]
>>I think a lot of interesting password policies could be implemented
>>if it was possible to run perl-code before and after existing
>>authentication modules. Is it feasible to add this to the current
>>mod_perl as a runtime option?
>
> runtime is not likely to be possible. I'm considering a patch that
> would make the hook behavior configurable as a compile-time option,
Instead of trying to cram multiple perl-script into the same Authen
phase, which btw could not be done without patching Apache and/or
mod_perl, I ended up using other phases but Authen. Other phases that
should not really be used for authentication like this and breaks a
few Apache rules.
I specifically had to change mod_auth_ so it returns sets a apache
note and returns DECLINED instead of stopping the whole request with a
HTTP_UNAUTHORIZED. The change is simple and can be applied to any auth
module without much effort.
So, I thought I'd ask the list for opinions regarding this
poor-mans-approach.
Here is the setup:
<Location /secure/>
AuthType Basic
AuthName "Secure Area"
Require valid-user
# Find userinfo in cache. If user is banned, return
# HTTP_UNAUTHORIZED else let him through to next handler
PerlAccessHandler MyApache::Bouncer
# The actual auth module. Patched so it creates an apache
# request note if user is unauthorized + let request through
# to next handler (DECLINED) _even tho_ user failed!
AuthExternal wicauth
# If apache note contains current user, update cache (nfailures
# count) and return HTTP_UNAUTHORIZED or return OK
PerlFixUpHandler MyApache::Ledger
</Location>
Here is my tidied error_log log which shows how it works.
[ User wic with wrong pwd below ]
Bouncer: wic not in cache. Letting through.
AuthExtern wicauth: Failed for user wic.
Ledger: wic not in cache. Adding.
Bouncer: wic in cache: 1 <--- nfailures
AuthExtern wicauth: Failed for user wic
Ledger: wic in cache. Updating.
[ ... 10 times or something like that ... ]
Bouncer: wic in cache: 10
AuthExtern wicauth: Failed for user wic.
Ledger: banning wic for 2 hours.
Bouncer: wic in cache: banned
Bouncer: wic is banned!
Bouncer: wic in cache: banned
Bouncer: wic is banned!
[ The user wic is banned and have to wait for 2 hours until Bouncer
will let him through. ]
Bouncer: wic banning time has expired. Letting through.
AuthExtern wicauth: OK accepted for user wic.
Ledger: wic login ok.
By keeping count like this (and assuming it works in a real
situation), one can device lots of cool ways to add login and password
policies. Just change relevant part in the Bouncer/Ledger.
(Btw, I am using Cache::FileCache to keep track of number of failed
retries.)