Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- revert feature 564: log the login of each user; but add the possibi…
…lity to be

done by a plugin
- create a "standard" way to define PHP functions that we use but might not be
available in the current php version
- when a comment is rejected (spam, anti-flood etc), put the content back to the
browser in case there is a real user behind it
- now a comment can be entered only if the page was retrieved between 2 seconds
ago and 1 hour ago

git-svn-id: http://piwigo.org/svn/trunk@1744 68402e56-0260-453c-a942-63ccdbb3a9ee
  • Loading branch information
rvelices committed Jan 23, 2007
1 parent 767064c commit e90aaff
Show file tree
Hide file tree
Showing 18 changed files with 174 additions and 98 deletions.
1 change: 0 additions & 1 deletion admin/configuration.php
Expand Up @@ -51,7 +51,6 @@
'log',
'history_admin',
'history_guest',
'login_history',
'email_admin_on_new_user',
'allow_user_registration',
);
Expand Down
19 changes: 2 additions & 17 deletions identification.php
Expand Up @@ -45,24 +45,9 @@
if (isset($_POST['login']))
{
$redirect_to = isset($_POST['redirect']) ? $_POST['redirect'] : '';
$username = mysql_escape_string($_POST['username']);
// retrieving the encrypted password of the login submitted
$query = '
SELECT '.$conf['user_fields']['id'].' AS id,
'.$conf['user_fields']['password'].' AS password
FROM '.USERS_TABLE.'
WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
;';
$row = mysql_fetch_array(pwg_query($query));
if ($row['password'] == $conf['pass_convert']($_POST['password']))
$remember_me = isset($_POST['remember_me']) and $_POST['remember_me']==1;
if ( try_log_user($_POST['username'], $_POST['password'], $remember_me) )
{
$remember_me = false;
if (isset($_POST['remember_me'])
and $_POST['remember_me'] == 1)
{
$remember_me = true;
}
log_user($row['id'], $remember_me);
redirect(empty($redirect_to) ? make_index_url() : $redirect_to);
}
else
Expand Down
11 changes: 11 additions & 0 deletions include/common.inc.php
Expand Up @@ -121,6 +121,17 @@
exit;
}

foreach( array(
'array_intersect_key', //PHP 5 >= 5.1.0RC1
'hash_hmac', //(hash) - enabled by default as of PHP 5.1.2
) as $func)
{
if (!function_exists($func))
{
include_once(PHPWG_ROOT_PATH . 'include/php_compat/'.$func.'.php');
}
}

include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
include(PHPWG_ROOT_PATH . 'include/constants.php');
Expand Down
1 change: 1 addition & 0 deletions include/functions_html.inc.php
Expand Up @@ -717,5 +717,6 @@ function set_status_header($code, $text='')
}
header("HTTP/1.1 $code $text");
header("Status: $code $text");
trigger_action('set_status_header', $code, $text);
}
?>
17 changes: 0 additions & 17 deletions include/functions_search.inc.php
Expand Up @@ -252,23 +252,6 @@ function get_regular_search_results($search)
return $items;
}


if (!function_exists('array_intersect_key')) {
function array_intersect_key()
{
$arrs = func_get_args();
$result = array_shift($arrs);
foreach ($arrs as $array) {
foreach ($result as $key => $v) {
if (!array_key_exists($key, $array)) {
unset($result[$key]);
}
}
}
return $result;
}
}

/**
* returns the LIKE sql clause corresponding to the quick search query $q
* and the field $field. example q="john bill", field="file" will return
Expand Down
42 changes: 37 additions & 5 deletions include/functions_user.inc.php
Expand Up @@ -858,8 +858,9 @@ function get_language_filepath($filename, $dirname = '')
/**
* returns the auto login key or false on error
* @param int user_id
* @param string [out] username
*/
function calculate_auto_login_key($user_id)
function calculate_auto_login_key($user_id, &$username)
{
global $conf;
$query = '
Expand All @@ -871,7 +872,12 @@ function calculate_auto_login_key($user_id)
if (mysql_num_rows($result) > 0)
{
$row = mysql_fetch_assoc($result);
$key = sha1( $row['username'].$row['password'] );
$username = $row['username'];
$data = $row['username'].$row['password'];
$key = base64_encode(
pack('H*', sha1($data))
.hash_hmac('md5', $data, $conf['secret_key'],true)
);
return $key;
}
return false;
Expand All @@ -889,7 +895,7 @@ function log_user($user_id, $remember_me)

if ($remember_me and $conf['authorize_remembering'])
{
$key = calculate_auto_login_key($user_id);
$key = calculate_auto_login_key($user_id, $username);
if ($key!==false)
{
$cookie = array('id' => (int)$user_id, 'key' => $key);
Expand Down Expand Up @@ -928,12 +934,13 @@ function auto_login() {
if ( isset( $_COOKIE[$conf['remember_me_name']] ) )
{
$cookie = unserialize(stripslashes($_COOKIE[$conf['remember_me_name']]));
if ($cookie!==false)
if ($cookie!==false and is_numeric(@$cookie['id']) )
{
$key = calculate_auto_login_key($cookie['id']);
$key = calculate_auto_login_key( $cookie['id'], $username );
if ($key!==false and $key===$cookie['key'])
{
log_user($cookie['id'], true);
trigger_action('login_success', $username);
return true;
}
}
Expand All @@ -942,6 +949,31 @@ function auto_login() {
return false;
}

/**
* Tries to login a user given username and password (must be MySql escaped)
* return true on success
*/
function try_log_user($username, $password, $remember_me)
{
global $conf;
// retrieving the encrypted password of the login submitted
$query = '
SELECT '.$conf['user_fields']['id'].' AS id,
'.$conf['user_fields']['password'].' AS password
FROM '.USERS_TABLE.'
WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
;';
$row = mysql_fetch_assoc(pwg_query($query));
if ($row['password'] == $conf['pass_convert']($password))
{
log_user($row['id'], $remember_me);
trigger_action('login_success', $username);
return true;
}
trigger_action('login_failure', $username);
return false;
}

/*
* Return access_type definition of uuser
* Test does with user status
Expand Down
35 changes: 35 additions & 0 deletions include/php_compat/array_intersect_key.php
@@ -0,0 +1,35 @@
<?php
// http://www.php.net/manual/en/function.array-intersect-key.php
// PHP 5 >= 5.1.0RC1
function array_intersect_key()
{
$args = func_get_args();
if (count($args) < 2) {
trigger_error('Wrong parameter count for array_intersect_key()', E_USER_WARNING);
return;
}

// Check arrays
$array_count = count($args);
for ($i = 0; $i !== $array_count; $i++) {
if (!is_array($args[$i])) {
trigger_error('array_intersect_key() Argument #' . ($i + 1) . ' is not an array', E_USER_WARNING);
return;
}
}

// Compare entries
$result = array();
foreach ($args[0] as $key1 => $value1) {
for ($i = 1; $i !== $array_count; $i++) {
foreach ($args[$i] as $key2 => $value2) {
if ((string) $key1 === (string) $key2) {
$result[$key1] = $value1;
}
}
}
}

return $result;
}
?>
25 changes: 25 additions & 0 deletions include/php_compat/hash_hmac.php
@@ -0,0 +1,25 @@
<?php
//(hash) - enabled by default as of PHP 5.1.2
function hash_hmac($algo, $data, $key, $raw_output=false)
{
/* md5 and sha1 only */
$algo=strtolower($algo);
$p=array('md5'=>'H32','sha1'=>'H40');
if ( !isset($p[$algo]) or !function_exists($algo) )
{
$algo = 'md5';
}
if(strlen($key)>64) $key=pack($p[$algo],$algo($key));
if(strlen($key)<64) $key=str_pad($key,64,chr(0));

$ipad=substr($key,0,64) ^ str_repeat(chr(0x36),64);
$opad=substr($key,0,64) ^ str_repeat(chr(0x5C),64);

$ret = $algo($opad.pack($p[$algo],$algo($ipad.$data)));
if ($raw_output)
{
$ret = pack('H*', $ret);
}
return $ret;
}
?>
38 changes: 10 additions & 28 deletions include/picture_comment.inc.php
Expand Up @@ -30,32 +30,6 @@
*
*/

if (!function_exists('hash_hmac'))
{
function hash_hmac($algo, $data, $key, $raw_output=false)
{
/* md5 and sha1 only */
$algo=strtolower($algo);
$p=array('md5'=>'H32','sha1'=>'H40');
if ( !isset($p[$algo]) or !function_exists($algo) )
{
$algo = 'md5';
}
if(strlen($key)>64) $key=pack($p[$algo],$algo($key));
if(strlen($key)<64) $key=str_pad($key,64,chr(0));

$ipad=substr($key,0,64) ^ str_repeat(chr(0x36),64);
$opad=substr($key,0,64) ^ str_repeat(chr(0x5C),64);

$ret = $algo($opad.pack($p[$algo],$algo($ipad.$data)));
if ($raw_output)
{
$ret = pack('H*', $ret);
}
return $ret;
}
}

//returns string action to perform on a new comment: validate, moderate, reject
function user_comment_check($action, $comment, $picture)
{
Expand Down Expand Up @@ -166,7 +140,8 @@ function user_comment_check($action, $comment, $picture)

$key = explode(':', @$_POST['key']);
if ( count($key)!=2
or $key[0]>time() or $key[0]<time()-1800 // 30 minutes expiration
or $key[0]>time()-2 // page must have been retrieved more than 2 sec ago
or $key[0]<time()-3600 // 60 minutes expiration
or hash_hmac('md5', $key[0], $conf['secret_key'])!=$key[1]
)
{
Expand Down Expand Up @@ -257,6 +232,7 @@ function user_comment_check($action, $comment, $picture)
}
else
{
set_status_header(403);
$template->assign_block_vars('information',
array('INFORMATION'=>l10n('comment_not_added') )
);
Expand Down Expand Up @@ -354,9 +330,15 @@ function user_comment_check($action, $comment, $picture)
{
$key = time();
$key .= ':'.hash_hmac('md5', $key, $conf['secret_key']);
$content = '';
if ('reject'===@$comment_action)
{
$content = htmlspecialchars($comm['content']);
}
$template->assign_block_vars('comments.add_comment',
array(
'key' => $key
'KEY' => $key,
'CONTENT' => $content
));
// display author field if the user is not logged in
if ($user['is_the_guest'])
Expand Down
14 changes: 1 addition & 13 deletions include/ws_functions.inc.php
Expand Up @@ -494,20 +494,8 @@ function ws_session_login($params, &$service)
{
return new PwgError(400, "This method requires POST");
}

$username = $params['username'];
// retrieving the encrypted password of the login submitted
$query = '
SELECT '.$conf['user_fields']['id'].' AS id,
'.$conf['user_fields']['password'].' AS password
FROM '.USERS_TABLE.'
WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
;';
$row = mysql_fetch_assoc(pwg_query($query));

if ($row['password'] == $conf['pass_convert']($params['password']))
if (try_log_user($params['username'], $params['password'],false))
{
log_user($row['id'], false);
return true;
}
return new PwgError(999, 'Invalid username/password');
Expand Down
1 change: 0 additions & 1 deletion install/config.sql
Expand Up @@ -21,7 +21,6 @@ INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('rate_anonymous',
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('page_banner','<h1>PhpWebGallery demonstration site</h1><p>My photos web site</p>','html displayed on the top each page of your gallery');
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('history_admin','false','keep a history of administrator visits on your website');
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('history_guest','true','keep a history of guest visits on your website');
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('login_history','true','keep a history of user logins on your website');
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('allow_user_registration','true','allow visitors to register?');
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('secret_key', MD5(RAND()), 'a secret key specific to the gallery for internal use');
-- Notification by mail
Expand Down
50 changes: 50 additions & 0 deletions install/db/46-database.php
@@ -0,0 +1,50 @@
<?php
// +-----------------------------------------------------------------------+
// | PhpWebGallery - a PHP based picture gallery |
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
// +-----------------------------------------------------------------------+
// | branch : BSF (Best So Far)
// | file : $Id$
// | last update : $Date$
// | last modifier : $Author$
// | revision : $Revision$
// +-----------------------------------------------------------------------+
// | This program is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation |
// | |
// | This program is distributed in the hope that it will be useful, but |
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
// | General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with this program; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
// | USA. |
// +-----------------------------------------------------------------------+

if (!defined('PHPWG_ROOT_PATH'))
{
die('Hacking attempt!');
}

$upgrade_description = 'remove login_history from #config (partial revert 30-database.php)';


// +-----------------------------------------------------------------------+
// | Upgrade content |
// +-----------------------------------------------------------------------+

$query = '
DELETE FROM '.PREFIX_TABLE.'config WHERE param="login_history"';
pwg_query($query);

echo
"\n"
.'"'.$upgrade_description.'"'.' ended'
."\n"
;

?>
1 change: 0 additions & 1 deletion language/en_UK.iso-8859-1/admin.lang.php
Expand Up @@ -106,7 +106,6 @@
$lang['Link all category elements to some existing categories'] = 'Link all category elements to some existing categories';
$lang['Linked categories'] = 'Linked categories';
$lang['Lock gallery'] = 'Lock gallery';
$lang['Login history'] = 'User login history';
$lang['Maintenance'] = 'Maintenance';
$lang['Manage permissions for a category'] = 'Manage permissions for a category';
$lang['Manage permissions for group "%s"'] = 'Manage permissions for group "%s"';
Expand Down
4 changes: 0 additions & 4 deletions language/en_UK.iso-8859-1/help/configuration.html
Expand Up @@ -40,10 +40,6 @@ <h3>General</h3>
will be saved.</li>

<li><strong>History Guests</strong>: page visits by guests will be saved.</li>

<li><strong>User login history</strong>: when a user logs in, it will be
logged in the <code>history</code> table.</li>

</ul>


Expand Down

0 comments on commit e90aaff

Please sign in to comment.