From f468fef5597b3f674a2647a41866c529e20aede4 Mon Sep 17 00:00:00 2001
From: Phyks
Date: Sat, 24 Aug 2013 23:28:56 +0200
Subject: [PATCH] Updated connexion form (may not work - not tested)
* Remember me option
* IP ban system (if IP differs from session stored one)
* Ban system if too many attempts
---
TODO | 1 +
inc/Ban.inc.php | 73 ++++++++++++++++
index.php | 83 +++++++++++++++----
install.php | 8 +-
....af3906cfde643ae7f290cfdc51cc9342.rtpl.php | 2 +
....af3906cfde643ae7f290cfdc51cc9342.rtpl.php | 7 +-
....36ba0f7e771a8681573a91518b54b424.rtpl.php | 0
....36ba0f7e771a8681573a91518b54b424.rtpl.php | 0
....af3906cfde643ae7f290cfdc51cc9342.rtpl.php | 0
....af3906cfde643ae7f290cfdc51cc9342.rtpl.php | 56 -------------
....af3906cfde643ae7f290cfdc51cc9342.rtpl.php | 1 +
tpl/connexion.html | 2 +
tpl/edit_users.html | 2 +-
tpl/settings.html | 1 +
14 files changed, 159 insertions(+), 77 deletions(-)
create mode 100644 inc/Ban.inc.php
mode change 100755 => 100644 tmp/connexion.af3906cfde643ae7f290cfdc51cc9342.rtpl.php
mode change 100755 => 100644 tmp/edit_users.af3906cfde643ae7f290cfdc51cc9342.rtpl.php
mode change 100755 => 100644 tmp/footer.36ba0f7e771a8681573a91518b54b424.rtpl.php
mode change 100755 => 100644 tmp/header.36ba0f7e771a8681573a91518b54b424.rtpl.php
mode change 100755 => 100644 tmp/index.af3906cfde643ae7f290cfdc51cc9342.rtpl.php
delete mode 100755 tmp/new_invoice.af3906cfde643ae7f290cfdc51cc9342.rtpl.php
mode change 100755 => 100644 tmp/settings.af3906cfde643ae7f290cfdc51cc9342.rtpl.php
diff --git a/TODO b/TODO
index 1cd34f7..6223546 100755
--- a/TODO
+++ b/TODO
@@ -5,6 +5,7 @@
* htmlspecialchars => on users objects
* handle negative amounts
* Refactor load method to avoir load_* methods !
+* Empêcher deux fois le même login
install.php :
=============
diff --git a/inc/Ban.inc.php b/inc/Ban.inc.php
new file mode 100644
index 0000000..fb3337d
--- /dev/null
+++ b/inc/Ban.inc.php
@@ -0,0 +1,73 @@
+array(),'BANS'=>array()),true).";\n?>");
+ include IPBANS_FILENAME;
+ // Signal a failed login. Will ban the IP if too many failures:
+ function ban_loginFailed()
+ {
+ $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS'];
+ if (!isset($gb['FAILURES'][$ip])) $gb['FAILURES'][$ip]=0;
+ $gb['FAILURES'][$ip]++;
+ if ($gb['FAILURES'][$ip]>(BAN_AFTER-1))
+ {
+ $gb['BANS'][$ip]=time()+BAN_DURATION;
+ logm('IP address banned from login');
+ }
+ $GLOBALS['IPBANS'] = $gb;
+ file_put_contents(IPBANS_FILENAME, "");
+ }
+
+ // Signals a successful login. Resets failed login counter.
+ function ban_loginOk()
+ {
+ $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS'];
+ unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]);
+ $GLOBALS['IPBANS'] = $gb;
+ file_put_contents(IPBANS_FILENAME, "");
+ logm('Login ok.');
+ }
+
+ // Checks if the user CAN login. If 'true', the user can try to login.
+ function ban_canLogin()
+ {
+ $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS'];
+ if (isset($gb['BANS'][$ip]))
+ {
+ // User is banned. Check if the ban has expired:
+ if ($gb['BANS'][$ip]<=time())
+ { // Ban expired, user can try to login again.
+ logm('Ban lifted.');
+ unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]);
+ file_put_contents(IPBANS_FILENAME, "");
+ return true; // Ban has expired, user can login.
+ }
+ return false; // User is banned.
+ }
+ return true; // User is not banned.
+ }
+
+ // Returns user IP
+ function user_IPs()
+ {
+ $ip = $_SERVER["REMOTE_ADDR"];
+ // Then we use more HTTP headers to prevent session hijacking from users behind the same proxy.
+ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$ip.'_'.$_SERVER['HTTP_X_FORWARDED_FOR']; }
+ if (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip=$ip.'_'.$_SERVER['HTTP_CLIENT_IP']; }
+ return $ip;
+ }
diff --git a/index.php b/index.php
index 193d2be..0da2244 100644
--- a/index.php
+++ b/index.php
@@ -1,11 +1,12 @@
assign('error', '');
$tpl->assign('base_url', htmlspecialchars(BASE_URL));
$tpl->assign('currency', htmlspecialchars(CURRENCY));
+ $tpl->assign('email_webmaster', htmlspecialchars(EMAIL_WEBMASTER));
+
+ // Set sessions parameters
+ ini_set('session.use_cookies', 1);
+ ini_set('session.use_only_cookies', 1);
+ ini_set('session.use_trans_sid', false);
+ session_name('bouffeatulm');
+
+ // Regenerate session if needed
+ $cookie = session_get_cookie_params();
+ $cookie_dir = ''; if(dirname($_SERVER['SCRIPT_NAME']) != '/') $cookie_dir = dirname($_SERVER['SCRIPT_NAME']);
+ session_set_cookie_params($cookie['lifetime'], $cookie_dir, $_SERVER['HTTP_HOST']);
+ session_regenerate_id(true);
// Handle current user status
- session_start();
+ if(session_id() == '') session_start();
+
+ // If IP has changed, logout
+ if(user_ip() != $_SESSION['ip']) {
+ session_destroy();
+ header('location: index.php?do=connect');
+ exit();
+ }
+
$current_user = new User();
if(isset($_SESSION['current_user'])) {
$current_user->sessionRestore($_SESSION['current_user'], true);
@@ -32,6 +54,7 @@
// If not connected, redirect to connection page
if($current_user === false && (empty($_GET['do']) OR $_GET['do'] != 'connect')) {
header('location: index.php?do=connect');
+ exit();
}
// Initialize empty $_GET['do'] if required to avoid error
@@ -44,17 +67,38 @@
case 'connect':
if($current_user !== false) {
header('location: index.php');
+ exit();
}
if(!empty($_POST['login']) && !empty($_POST['password'])) {
$user = new User();
$user->setLogin($_POST['login']);
- if($user->exists($_POST['login']) && $user->checkPassword($_POST['password'])) {
- $_SESSION['current_user'] = $user->sessionStore();
- header('location: index.php');
- exit();
+ if(ban_canLogin() == false) {
+ $error = "Unknown username / password.";
}
else {
- $error = "Unknown username/password.";
+ if($user->exists($_POST['login']) && $user->checkPassword($_POST['password'])) {
+ ban_loginOk();
+ $_SESSION['current_user'] = $user->sessionStore();
+ $_SESSION['ip'] = user_ip();
+
+ if(!empty($_POST['remember_me'])) { // Handle remember me cookie
+ $_SESSION['remember_me'] = 31536000;
+ }
+ else {
+ $_SESSION['remember_me'] = 0;
+ }
+
+ $cookie_dir = ''; if(dirname($_SERVER['SCRIPT_NAME']) != '/') $cookie_dir = dirname($_SERVER['SCRIPT_NAME']);
+ session_set_cookie_params($_SESSION['remember_me'], $cookie_dir, $_SERVER['HTTP_HOST']);
+ session_regenerate_id(true);
+
+ header('location: index.php');
+ exit();
+ }
+ else {
+ ban_loginFailed();
+ $error = "Unknown username/password.";
+ }
}
}
$tpl->assign('connection', true);
@@ -72,7 +116,7 @@
case 'password':
if(!empty($_POST['password']) && !empty($_POST['password_confirm'])) {
if($_POST['password'] == $_POST['password_confirm']) {
- $current_user->setPassword($user->encrypt($_POST['password']));
+ $current_user->setPassword($current_user->encrypt($_POST['password']));
$current_user->save();
header('location: index.php');
@@ -90,6 +134,7 @@
case 'add_user':
if(!$current_user->getAdmin()) {
header('location: index.php');
+ exit();
}
if(!empty($_POST['login']) && !empty($_POST['display_name']) && (!empty($_POST['password']) || !empty($_POST['user_id'])) && isset($_POST['admin'])) {
@@ -98,7 +143,7 @@
$user->setId($_POST['user_id']);
}
$user->setLogin($_POST['login']);
- $user->setDisplayName($_POST['login']);
+ $user->setDisplayName($_POST['display_name']);
if(!empty($_POST['password'])) {
$user->setPassword($user->encrypt($_POST['password']));
}
@@ -157,7 +202,7 @@
break;
case 'settings':
- if(!empty($_POST['mysql_host']) && !empty($_POST['mysql_login']) && !empty($_POST['mysql_db']) && !empty($_POST['currency']) && !empty($_POST['instance_title']) && !empty($_POST['base_url']) && !empty($_POST['timezone'])) {
+ if(!empty($_POST['mysql_host']) && !empty($_POST['mysql_login']) && !empty($_POST['mysql_db']) && !empty($_POST['currency']) && !empty($_POST['instance_title']) && !empty($_POST['base_url']) && !empty($_POST['timezone']) && !empty($_POST['email_webmaster'])) {
if(!is_writable('data/')) {
$tpl>assign('error', 'The script can\'t write in data/ dir, check permissions set on this folder.');
}
@@ -165,21 +210,23 @@
foreach($config as $line_number=>$line) {
if(strpos($line, "MYSQL_HOST") !== FALSE)
- $config[$line_number] = "\tdefine('".$_POST['mysql_host']."');\n";
+ $config[$line_number] = "\tdefine('MYSQL_HOST', '".$_POST['mysql_host']."');\n";
elseif(strpos($line, "MYSQL_LOGIN") !== FALSE)
- $config[$line_number] = "\tdefine('".$_POST['mysql_login']."');\n";
+ $config[$line_number] = "\tdefine('MYSQL_LOGIN', '".$_POST['mysql_login']."');\n";
elseif(strpos($line, "MYSQL_PASSWORD") !== FALSE && !empty($_POST['mysql_password']))
- $config[$line_number] = "\tdefine('".$_POST['mysql_password']."');\n";
+ $config[$line_number] = "\tdefine('MYSQL_PASSWORD', '".$_POST['mysql_password']."');\n";
elseif(strpos($line, "MYSQL_DB") !== FALSE)
- $config[$line_number] = "\tdefine('".$_POST['mysql_db']."');\n";
+ $config[$line_number] = "\tdefine('MYSQL_DB', '".$_POST['mysql_db']."');\n";
elseif(strpos($line, "MYSQL_PREFIX") !== FALSE && !empty($_POST['mysql_prefix']))
- $config[$line_number] = "\tdefine('".$_POST['mysql_prefix']."');\n";
+ $config[$line_number] = "\tdefine('MYSQL_PREFIX', '".$_POST['mysql_prefix']."');\n";
elseif(strpos($line, "INSTANCE_TITLE") !== FALSE)
- $config[$line_number] = "\tdefine('".$_POST['instance_title']."');\n";
+ $config[$line_number] = "\tdefine('INSTANCE_TITLE', '".$_POST['instance_title']."');\n";
elseif(strpos($line, "BASE_URL") !== FALSE)
- $config[$line_number] = "\tdefine('".$_POST['base_url']."');\n";
+ $config[$line_number] = "\tdefine('BASE_URL', '".$_POST['base_url']."');\n";
elseif(strpos($line, "CURRENCY") !== FALSE)
- $config[$line_number] = "\tdefine('".$_POST['currency']."');\n";
+ $config[$line_number] = "\tdefine('CURRENCY', '".$_POST['currency']."');\n";
+ elseif(strpos($line, "EMAIL_WEBMASTER") !== FALSE)
+ $config[$line_number] = "\tdefine('EMAIL_WEBMASTER', '".$_POST['email_webmaster']."');\n";
elseif(strpos($line_number, 'date_default_timezone_set') !== FALSE)
$config[$line_number] = "\tdate_default_timezone_set('".$_POST['timezone']."');\n";
}
diff --git a/install.php b/install.php
index 7f5c0a1..bcd0575 100644
--- a/install.php
+++ b/install.php
@@ -11,7 +11,7 @@
$block_form = true;
}
- if(!empty($_POST['mysql_host']) && !empty($_POST['mysql_login']) && !empty($_POST['mysql_db']) && !empty($_POST['admin_login']) && !empty($_POST['admin_password']) && !empty($_POST['currency']) && !empty($_POST['instance_title']) && !empty($_POST['base_url']) && !empty($_POST['timezone'])) {
+ if(!empty($_POST['mysql_host']) && !empty($_POST['mysql_login']) && !empty($_POST['mysql_db']) && !empty($_POST['admin_login']) && !empty($_POST['admin_password']) && !empty($_POST['currency']) && !empty($_POST['instance_title']) && !empty($_POST['base_url']) && !empty($_POST['timezone']) && !empty($_POST['email_webmaster'])) {
$mysql_host = $_POST['mysql_host'];
$mysql_login = $_POST['mysql_login'];
$mysql_db = $_POST['mysql_db'];
@@ -35,6 +35,10 @@
} catch (PDOException $e) {
$error = 'Unable to connect to database, check your credentials and config.
Error message : '.$e->getMessage().'.';
}
+
+ if(!filter_var($_POST['email_webmaster'], FILTER_VALIDATE_EMAIL)) {
+ $email = 'Webmaster\'s e-mail address is invalid.';
+ }
if(empty($error)) {
if(function_exists('mcrypt_create_iv')) {
@@ -57,6 +61,7 @@
define('BASE_URL', '".$_POST['base_url']."');
define('SALT', '".$salt."');
define('CURRENCY', '".$_POST['currency']."');
+ define('EMAIL_WEBMASTER', '".$_POST['email_webmaster']."');
date_default_timezone_set('".$_POST['timezone']."');
";
@@ -126,6 +131,7 @@
For example : Europe/Paris. See the doc for more info.
+