Apache Authentication
=====================

These are two php examples of calling ibd-ban from php when 
authentication fails, in order to prevent brute force attacks.

Apache can run custom PHP scripts for various error codes.  
Authentication is related to response code 401, thus you may have your 
script invoked by setting

	ErrorDocument 401 /my_401_handler.php

along with directives like Require, AuthType, etcetera.  The handler 
code may be like in the following snippet, if PHP runs as an Apache 
module.

-----8<-----
<?php

function first_of($ar)
{
	foreach ($ar as $i)
		if (!empty($_SERVER[$i]))
			return $_SERVER[$i];
	return '';
}

	header('Status: 401 Authorization Required');

	$adjective = 'Required';
	$user = 'Unknown';
	$do_ban = 0;

	# PHP sets these when the client sends an 'Authorization' header,
	# so the user is trying a password (as opposed to just hitting cancel)
	if (isset($_SERVER['PHP_AUTH_DIGEST']))
	{
		$data = array();
		$matches = array();
		preg_match_all('/(\w+)=(?:(?>"((?>[^"\\\\]|\\\\.)+)")|([^"\s,=]+))/',
			$_SERVER['PHP_AUTH_DIGEST'], $matches, PREG_SET_ORDER);

		foreach ($matches as $m)
			$data[strtolower($m[1])] =
				empty($m[3])? preg_replace('/\\\\(.)/', '$1', $m[2]): $m[3];

		if (isset($data['username']) && isset($data['response']))
		{
			$do_ban = 1;
			$user = $data['username'];
		}
	}
	else if (isset($_SERVER['PHP_AUTH_USER']) &&
		isset($_SERVER['PHP_AUTH_PW']))
	{
		$do_ban = 1;
		$user = $_SERVER['PHP_AUTH_USER'];
	}
	
	if ($do_ban)
	{
		$adjective = 'Failed';
		$msg = 'Failed access to '.
			first_of(array('REDIRECT_SCRIPT_URI', 'SCRIPT_URI',
				'REDIRECT_SCRIPT_URL', 'SCRIPT_URL', 'SERVER_NAME')) .
			' by '. $user;

		$addr = first_of(array('REDIRECT_REMOTE_ADDR', 'REMOTE_ADDR'));
		if (!empty($addr))
		{
			$msg .= ' at '. $addr;
			$rtc = 0;
			$nu = array();
			exec("/usr/local/bin/ibd-ban -e -i ". $addr .
				" --reason=\"Apache login\" --log-syslog",
				$nu,
				$rtc);
			$msg .= " ibd-ban rtc: $rtc";
		}
		syslog(LOG_AUTH|LOG_WARNING, $msg);
	}

	echo '<html><head><title>401 Authorization '. $adjective .'</title></head>'.
		'<body><h1>401 Authorization '. $adjective .'</h1>';

	if ($do_ban)
		echo '<p>Failed attempt from user '. $user .' has been logged.</p>';
	else
		echo '<p>Please submit credentials.</p>';

	echo '<p>'.
		first_of(array('SERVER_ADMIN', 'SERVER_SIGNATURE', 'SERVER_NAME'));
	echo '</p></body></html>';
?>
----->8-----


MediaWiki
=========

Add the following snippet near the end of your LocalSettings.php

-----8<-----
# catch dictionary attacks
function myBanDictionaryAttack($response, $user, $username)
{
        if (isset($_SERVER['REMOTE_ADDR']))
        {
                $msg = "wiki user ".
                        $username ." rtc: ". $response->status ." from ".
                        $_SERVER['REMOTE_ADDR'];
                if ($response->status != 'PASS')
                {
                        $rtc = 0;
                        $nu = array();
                        exec("/usr/local/bin/ibd-ban -e -i ".
                                $_SERVER['REMOTE_ADDR']
                                ." --reason=\"my wiki login\" --log-syslog",
                                $nu,
                                $rtc);
                        $msg .= " ibd-ban rtc: $rtc";
                }
                syslog(LOG_AUTH|LOG_WARNING, $msg);
        }
        return true;
}

$wgHooks['AuthManagerLoginAuthenticateAudit'][] = 'myBanDictionaryAttack';

----->8-----
