BeCastWebEngine/inc/sessions.class.php
2025-06-22 17:45:42 +02:00

396 lines
16 KiB
PHP

<?php
$module["session"]["name"]="Sessionmanagement Module";
$module["session"]["ver"]="0.9.1";
/**
* Project: astat - simple site engine
* File: /inc/sessions.class.php
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* @link http://www.astat.org SVN: $URL: http://svn.astat.org/astat/trunk/inc/sessions.class.php $
* @copyright 2010 becast.at
* @author Bernhard Jaud <bernhard at becast dot at>
* @package astat core
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id$
*/
class session {
var $sid = 0;
var $uid = 0;
var $ip = '';
var $packip = '';
var $userdata = array();
var $useragent = '';
function page_begin($page = "UNDEFINED", $needlogin = TRUE){
global $config, $db, $log, $core, $lang, $plugin, $functions;
$plugin->run_hook('page_begin_start',array('page'=>$page,'needlogin'=>$needlogin));
if($this->userdata['uid']==0 || !$this->userdata['uid']){
$this->ip = $functions->get_ip();
$this->packip = $functions->my_inet_pton($this->ip);
$this->useragent = $_SERVER["HTTP_USER_AGENT"];
//Check if the User has a Cookie
if (isset($_COOKIE[$config["cookiename"] . "_sid"])){
//Retireve Data from Cookie
$sid = $_COOKIE[$config["cookiename"] . "_sid"];
$sid = $db->escape(base64_decode($sid));
$data = $db->fetch_array($db->query("SELECT sid,uid FROM `" . $config["prefix"] . "sessions` WHERE `sid`='".$sid."' AND `ip`=".$db->escape_binary($this->packip)));
if($data['sid']){
$this->sid=$data['sid'];
$this->uid=$data['uid'];
}else{
$this->sid=0;
$this->uid=0;
}
}
//Something's rotten. Still no SID.
if(!$this->sid){
//This is some strange behavior, log it with low priority.
if($config["logging"])
$log->write("SID not set.",5,__LINE__,__FILE__);
$this->sid = 0;
$this->uid = 0;
}
// If there is a Cookie log the user in (if he isn't already)
if (isset($_COOKIE[$config["cookiename"] . "_base"])){
$cookiedata = $_COOKIE[$config["cookiename"] . "_base"];
$cookiedata = explode("_",base64_decode($cookiedata),2);
$this->load_data($cookiedata[0],$cookiedata[1]);
}
if($this->userdata['active']==2){
$additional_message = '';
if($this->userdata['bio']!=""){
$additional_message = '<br />'.$lang->_('REASON').' '.$this->userdata['bio'];
}
//$this->destroy_session($session->sid);
$this->userdata['uid']=0;
$this->setcookie($config['cookiename'] . '_base', 0, time()-3600, $config['path'],$config['domain']);
$core->message($lang->_('BANNED'),$lang->_('YOUHAVEBEENBANNED').$additional_message);
}
// Still no Userdata, its a Guest
if(!isset($this->userdata['uid'])){
if(!empty($this->sid)){
$this->update_session($this->sid);
$this->userdata['uid']=0;
}else{
$this->create_session();
$this->userdata['uid']=0;
}
}
$this->setcookie($config["cookiename"] . "_sid",base64_encode($this->sid),0,"/",$config['domain'],true);
}
$plugin->run_hook('page_begin_end',array('data'=>$this));
if($needlogin != FALSE && $this->userdata["uid"]==0){
header("LOCATION://" . $_SERVER["HTTP_HOST"] . $config['path'] . "/index.php?fail=needlogin");
}
}
//Fetch userdata
function load_data($uid, $loginkey){
global $db,$config, $log, $plugin, $lang;
$plugin->run_hook('load_data_start',array('loginkey'=>$loginkey,'uid'=>$uid, 'data'=>$this));
$result = $db->query("SELECT * FROM `" . $config["prefix"] . "users` u LEFT JOIN `" . $config["prefix"] . "role` r ON r.id=u.role WHERE u.`uid`='" . intval($uid) . "' and u.`loginkey`='" . $db->escape($loginkey) . "' LIMIT 1");
$this->userdata=$db->fetch_array($result);
$result = $db->query("SELECT * FROM `" . $config["prefix"] . "roleset` rs LEFT JOIN `" . $config["prefix"] . "role_values` rv ON rv.id=rs.role_value_id WHERE rs.role_id='".$this->userdata["role"]."'");
while($row=$db->fetch_array($result)){
$this->userdata[$row["name"]]=$row["value"];
}
if(!$this->userdata['uid']){
if($config["logging"])
$log->write("No User found. UID: " .$uid,4,__LINE__,__FILE__);
unset($this->userdata);
$this->uid=0;
return false;
}
if($uid!=$this->userdata['uid'] || $loginkey!=$this->userdata['loginkey']){
if($config["logging"]){
$log->write("HACK ATTEMPT. Cookie Spoof. UID: " .$uid,1,__LINE__,__FILE__);
}
unset($this->userdata);
$this->uid=0;
return false;
}
if($this->userdata['uid']!=0){
if($this->userdata['lastip'] != $this->packip && array_key_exists('lastip', $this->userdata)){
$lastip_add = ", lastip=".$db->escape_binary($this->packip);
}
else
{
$lastip_add = '';
}
$time = time();
if($time - $this->userdata['lastactive'] > 900){
$db->query("UPDATE `" . $config["prefix"] . "users` SET `lastvisit`='" . $this->userdata['lastactive'] . "', `lastactive`='" . $time . "'".$lastip_add." WHERE `uid`='" . $uid . "'");
//$mybb->user['lastvisit'] = $mybb->user['lastactive'];
}
else
{
$timespent = $time - $this->userdata['lastactive'];
$db->query("UPDATE `" . $config["prefix"] . "users` SET `lastactive`='" . $time . "'".$lastip_add." WHERE `uid`='" . $uid . "'");
}
}
if(!empty($this->sid)){
$this->update_session($this->sid, $this->userdata['uid']);
}else{
$this->create_session($this->userdata['uid']);
}
$lang->setlang($this->userdata['lang']);
$plugin->run_hook('load_data_end',array('data'=>$this));
}
function setcookie($name,$data,$validto=0,$path=NULL,$domain=NULL,$httponly=false,$https=true)
{
if($domain!=''){
// Fix the domain to accept domains with and without 'www.'.
if (strtolower( substr($domain, 0, 4) ) == 'www.' ){
$domain = substr($domain, 4);
}else{
$domain = $domain;
}
// Add the dot prefix to ensure compatibility with subdomains
if ( substr($domain, 0, 1) != '.' ){
$domain = '.'.$domain;
}
}
if((isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) || $https){
$https = true;
}
$arr_cookie_options = array (
'expires' => $validto,
'path' => $path,
'domain' => $domain, // leading dot for compatibility or use subdomain
'secure' => $https, // or false
'httponly' => $httponly, // or false
'samesite' => 'Strict' // None || Lax || Strict
);
setcookie($name, $data, $arr_cookie_options);
}
function update_session($sid, $uid=''){
global $db,$config, $plugin, $lang;
$plugin->run_hook('update_session_start', array('sid'=>$sid,'uid'=>$uid, 'data'=>$this));
if($uid){
$sessiondata['uid'] = $uid;
$db->query("UPDATE `" . $config["prefix"] . "users` SET `lastvisit`='".time()."' WHERE `uid`='".$uid."'");
}else{
$sessiondata['uid'] = 0;
$lang->setlang($config['lang']);
}
$sid = $db->escape($sid);
$db->query("UPDATE `" . $config["prefix"] . "sessions` SET `uid`='".$sessiondata['uid']."',`time`='".time()."',`ip`=".$db->escape_binary($this->packip).", `useragent`='".$db->escape($this->useragent)."' WHERE `sid`='".$sid."'");
$timeout=time()-1800;
$db->query("DELETE FROM `" . $config["prefix"] . "sessions` WHERE `time`<='".$timeout."'");
$plugin->run_hook('update_session_end');
}
function create_session($uid=0){
global $db,$config, $plugin, $lang, $functions;
$plugin->run_hook('create_session_start', array('uid'=>$uid, 'data'=>$this));
if($uid > 0){
$db->query("DELETE FROM `" . $config["prefix"] . "sessions` WHERE `uid`='".intval($uid)."'");
$sessiondata['uid'] = $uid;
}else{
$db->query("DELETE FROM `" . $config["prefix"] . "sessions` WHERE `ip`=".$db->escape_binary($this->packip));
$sessiondata['uid'] = 0;
$lang->setlang($config['lang']);
}
$sessiondata['sid'] = md5($functions->random_str(50));
$db->query("INSERT INTO `" . $config["prefix"] . "sessions` (`sid`,`uid`,`time`,`useragent`,`ip`) VALUES ('".$sessiondata['sid']."','".$sessiondata['uid']."','".time()."','".$db->escape($this->useragent)."',".$db->escape_binary($this->packip).")");
$db->query("UPDATE `" . $config["prefix"] . "users` SET `lastvisit`='".time()."' WHERE `uid`='".$uid."'");
$this->sid = $sessiondata['sid'];
$this->uid = $sessiondata['uid'];
$plugin->run_hook('create_session_end');
}
function destroy_session($sid)
{
global $db,$config, $plugin;
$plugin->run_hook('destroy_session_start', array('data'=>$this));
if($sid !=""){
$db->query("DELETE FROM `" . $config["prefix"] . "sessions` WHERE `sid`='".$db->escape($sid)."'");
}else{
$db->query("DELETE FROM `" . $config["prefix"] . "sessions` WHERE `ip`=".$db->escape_binary($this->packip));
}
unset($this->userdata);
$this->setcookie($config["cookiename"] . '_sid','',-3600,'/',true);
$this->sid = 0;
$this->uid = 0;
$plugin->run_hook('destroy_session_end');
}
function check_login($username='',$password='',$openid='')
{
global $db,$config, $plugin, $lang, $core;
$plugin->run_hook('check_login_start', array('data'=>$this));
if($username!='' && $password!=''){
$username = $db->escape($username);
$result = $db->query("SELECT `uid`,`salt` FROM `" . $config['prefix'] . "users` WHERE `username` LIKE '".$username."' AND `active`>'0' LIMIT 1");
if ($db->num_rows ($result) > 0){
// There is a user
$data=$db->fetch_array($result);
}else{
return false;
}
$pass = hash('sha256',$db->escape($data['salt'].$password));
$result = $db->query("SELECT `uid`,`loginkey`,`active`,`bio` FROM `" . $config['prefix'] . "users` WHERE `username` LIKE '".$username."' AND `password`='".$pass."' AND `active`>'0' LIMIT 1");
if ($db->num_rows ($result) > 0){
// There is a user
$data=$db->fetch_array($result);
}else{
return false;
}
if($data['active']==2){
$additional_message = '';
if($data['bio']!=""){
$additional_message = '<br />'.$lang->_('REASON').' '.$data['bio'];
}
unset($data);
$this->setcookie($config['cookiename'] . '_base', 0, time()-3600, $config['path'],$config['domain']);
$core->message($lang->_('BANNED'),$lang->_('YOUHAVEBEENBANNED').$additional_message);
return 'BANNED';
}
$uid = $data['uid'];
$key = $data['loginkey'];
$this->login($uid,$key);
return $uid;
}elseif($openid!=''){
$identity=$db->escape($openid);
$result = $db->query("SELECT `uid`,`loginkey` FROM `" . $config['prefix'] . "users` WHERE `openid_identity` = '".$identity."' AND `active`='1' LIMIT 1");
if ($db->num_rows ($result) > 0){
// There is a user
$data=$db->fetch_array($result);
}else{
return false;
}
$uid = $data['uid'];
$key = $data['loginkey'];
$this->login($uid,$key);
return $uid;
}else{
return false;
}
}
function login($uid,$key)
{
global $db,$config, $plugin;
$plugin->run_hook('logon_start', array('data'=>$this));
$cookiedata['uid'] = $uid;
$cookiedata['loginkey'] = $key;
$cookiedata = base64_encode($cookiedata['uid'] .'_'. $cookiedata['loginkey']);
if(isset($_POST['remember']) && $_POST['remember']){
$this->setcookie($config['cookiename'] . '_base', $cookiedata, time() + 60 * 60 * 24 * 365, $config['path'],$config['domain'],true);
}else{
$this->setcookie($config['cookiename'] . '_base', $cookiedata, 0, $config['path'],$config['domain'],true);
}
$this->create_session($uid);
$plugin->run_hook('logon_end');
}
function get_users_with_right($right, $value)
{
global $db,$config;
$result = $db->query("SELECT u.* FROM `" . $config["prefix"] . "users` u LEFT JOIN `" . $config["prefix"] . "role` r ON u.`role`=r.`id` LEFT JOIN `" . $config["prefix"] . "roleset` rs ON rs.`role_id`=r.`id` LEFT JOIN `" . $config["prefix"] . "role_values` rv ON rv.`id`=rs.`role_value_id` WHERE rv.`name`='".$db->escape($right)."' AND rs.`value`='".$db->escape($value)."'");
while($row=$db->fetch_array($result)){
$return[]=$row;
}
return $return;
}
function generate_Key($length=8){
$dummy = array_merge(range('0', '9'), range('a', 'z'), range('A', 'Z'));
mt_srand((double)microtime()*1000000);
for ($i = 1; $i <= (count($dummy)*2); $i++){
$swap = mt_rand(0,count($dummy)-1);
$tmp = $dummy[$swap];
$dummy[$swap] = $dummy[0];
$dummy[0] = $tmp;
}
return substr(implode('',$dummy),0,$length);
}
function sanitize_username($username){
global $config;
$username = trim($username);
$username = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $username);
$username = str_replace(array(chr(160), chr(173), chr(0xCA), chr(8238), chr(8237), chr(8203),"]","[","/","\\"), array("", "-", "", "", "", "","","","",""), $username);
// Remove multiple spaces from the username
$username = preg_replace("#\s{2,}#", "", $username);
return $username;
}
function verify_username($username){
global $config;
// Check if the username is not empty.
if($username == '')
{
return "Username empty.";
}
// Check if the username belongs to the list of banned usernames.
$banned=explode("\n",$config['banned_usernames']);
if(is_array($banned)){
foreach($banned as $banned_username){
$banned_username = str_replace('*', '(.*)', trim($banned_username));
if(preg_match("#\b{$banned_username}\b#i", $username)){
return "Forbidden Username:".$banned_username;
}
}
}
// Check for certain characters in username (<, >, &, commas and slashes)
if(strpos($username, ".") !== false || strpos($username, ":") !== false || strpos($username, " ") !== false || strpos($username, "<") !== false || strpos($username, ">") !== false || strpos($username, "&") !== false || strpos($username, ")") !== false || strpos($username, "(") !== false || strpos($username, "\\") !== false || strpos($username, ";") !== false || strpos($username, ",") !== false || strpos($username, "~") !== false)
{
return "Forbidden Chars in Username";
}
// Check if the username is of the correct length.
if(($config['maxnamelength'] != 0 && strlen($username) > $config['maxnamelength']) || ($config['minnamelength'] != 0 && strlen($username) < $config['minnamelength']))
{
return sprintf('The username must be %s Chars minimum and can be %s Chars long at max.',$config['minnamelength'],$config['maxnamelength']);
}
return true;
}
}
?>