Tie AuthProxy.pm to brute-force prevention setup
authorDan Wells <dbw2@calvin.edu>
Mon, 16 Jan 2012 20:13:43 +0000 (15:13 -0500)
committerDan Wells <dbw2@calvin.edu>
Sat, 10 Mar 2012 02:51:56 +0000 (21:51 -0500)
Attempts to authenticate using either normal auth or
AuthProxy.pm will now reference the same counter for
the purposes of preventing brute-force password attacks.

Signed-off-by: Dan Wells <dbw2@calvin.edu>
Signed-off-by: Dan Scott <dscott@laurentian.ca>
Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm

index c165462..9f1ce8c 100644 (file)
@@ -30,6 +30,7 @@ use strict;
 use warnings;
 use OpenILS::Application;
 use base qw/OpenILS::Application/;
 use warnings;
 use OpenILS::Application;
 use base qw/OpenILS::Application/;
+use OpenSRF::Utils::Cache;
 use OpenSRF::Utils::Logger qw(:logger);
 use OpenSRF::Utils::SettingsClient;
 use OpenILS::Application::AppUtils;
 use OpenSRF::Utils::Logger qw(:logger);
 use OpenSRF::Utils::SettingsClient;
 use OpenILS::Application::AppUtils;
@@ -45,10 +46,25 @@ my $U = 'OpenILS::Application::AppUtils';
 my @authenticators;
 my %authenticators_by_name;
 my $enabled = 'false';
 my @authenticators;
 my %authenticators_by_name;
 my $enabled = 'false';
+my $cache = OpenSRF::Utils::Cache->new();
+my $seed_timeout;
+my $block_timeout;
+my $block_count;
 
 sub initialize {
     my $conf = OpenSRF::Utils::SettingsClient->new;
 
 sub initialize {
     my $conf = OpenSRF::Utils::SettingsClient->new;
-    my @pfx = ( "apps", "open-ils.auth_proxy", "app_settings" );
+
+    my @pfx = ( "apps", "open-ils.auth", "app_settings", "auth_limits" );
+
+    # read in (or set defaults) for brute force blocking settings
+    $seed_timeout = $conf->config_value( @pfx, "seed_timeout" );
+    $seed_timeout = 30 if (!$seed_timeout or $seed_timeout < 0);
+    $block_timeout = $conf->config_value( @pfx, "seed_timeout" );
+    $block_timeout = $seed_timeout * 3 if (!$block_timeout or $block_timeout < 0);
+    $block_count = $conf->config_value( @pfx, "block_count" );
+    $block_count = 10 if (!$block_count or $block_count < 0);
+
+    @pfx = ( "apps", "open-ils.auth_proxy", "app_settings" );
 
     $enabled = $conf->config_value( @pfx, 'enabled' );
 
 
     $enabled = $conf->config_value( @pfx, 'enabled' );
 
@@ -157,6 +173,19 @@ sub login {
     return OpenILS::Event->new( 'LOGIN_FAILED' )
       unless (&enabled() and ($args->{'username'} or $args->{'barcode'}));
 
     return OpenILS::Event->new( 'LOGIN_FAILED' )
       unless (&enabled() and ($args->{'username'} or $args->{'barcode'}));
 
+    # check for possibility of brute-force attack
+    my $fail_count;
+    # since barcode logins are for 'native' only, we will rely on the blocking
+    # code built-in to 'native' for those logins
+    if ($args->{'username'}) {
+        $fail_count = $cache->get_cache('oils_auth_' . $args->{'username'} . '_count') || 0;
+        if ($fail_count >= $block_count) {
+            $logger->debug("AuthProxy found too many recent failures for '" . $args->{'username'} . "' : $fail_count, forcing failure state.");
+            $cache->put_cache('oils_auth_' . $args->{'username'} . '_count', ++$fail_count, $block_timeout);
+            return OpenILS::Event->new( 'LOGIN_FAILED' );
+        }
+    }
+
     my @error_events;
     my $authenticated = 0;
     my $auths;
     my @error_events;
     my $authenticated = 0;
     my $auths;
@@ -198,6 +227,10 @@ sub login {
     }
 
     # if we got this far, we failed
     }
 
     # if we got this far, we failed
+    # increment the brute force counter if 'native' didn't already
+    if ($args->{'username'} and !exists $authenticators_by_name{'native'}) {
+        $cache->put_cache('oils_auth_' . $args->{'username'} . '_count', ++$fail_count, $block_timeout);
+    }
     # TODO: send back some form of collected error events
     return OpenILS::Event->new( 'LOGIN_FAILED' );
 }
     # TODO: send back some form of collected error events
     return OpenILS::Event->new( 'LOGIN_FAILED' );
 }