TCExam文件代码注释分析(shard/code/tce_authorization.php)此版本为:12.0.012
TCExam 预先设定了用户有10个级别:
0 = anonymous user (unregistered).匿名、未注册者、游客
1 = basic user (registered);已注册会员
2-9 = configurable/custom levels;自定义级别
10 = administrator 管理员
<?php
/**
* 检查用户授权级别
* 这个脚本处理用户的会话
* TCExam 预先设定了用户有10个级别:
* 0 = anonymous user (unregistered).匿名、未注册者、游客
* 1 = basic user (registered);已注册会员
* 2-9 = configurable/custom levels;自定义级别
* 10 = administrator 管理员
*/
require_once('../config/tce_config.php');
require_once('../../shared/code/tce_functions_authorization.php');
require_once('../../shared/code/tce_functions_session.php');
require_once('../../shared/code/tce_functions_otp.php');
$logged = false; //用户没有登录
$PHPSESSIDSQL = F_escape_sql($PHPSESSID); //对当前用户活动号(字符串)进行安全过滤
$session_hash = getPasswordHash($PHPSESSID.getClientFingerprint());
$sqls = 'SELECT * FROM '.K_TABLE_SESSIONS.' WHERE cpsession_id=\''.$PHPSESSIDSQL.'\'';
if($rs = F_db_query($sqls, $db)){
if($ms = F_db_fetch_array($rs)){ //如果当前活动用户session已存在
session_decode($ms['cpsession_data']); //session_decode()函数可将 Session 资料解码。成功则返回 true 值。解码会话数据
if (K_CHECK_SESSION_FINGERPRINT AND ((!isset($_SESSION['session_hash'])) OR ($_SESSION['session_hash'] != $session_hash))){
session_regenerate_id(); //用于更改当前session_id的值,并保留session数组中的值。session_regenerate_id()有一个参数,默认为false。如果设置为true,则更变当前session_id的值,并清空当前session数组。
F_login_form(); //显示登录页面
exit();
}
$expiry = date(K_TIMESTAMP_FORMAT, (time() + K_SESSION_LIFE)); //修改当前活动用户session有效期时间
$sqlx = 'UPDATE '.K_TABLE_SESSIONS.' SET cpsession_expiry=\''.$expiry.'\' WHERE cpsession_id=\''.$PHPSESSIDSQL.'\'';
if (!$rx = F_db_query($sqlx, $db)) {
F_display_db_error();
}
}
else{ //如果在数据库找到与$PHPSESSIDSQL一样的活动用户session,就新建一个匿名活动用户session
$_SESSION['session_hash'] = $session_hash;
$_SESSION['session_user_id'] = 1;
$_SESSION['session_user_name'] = '- ['.substr($PHPSESSID, 12, 8).']';
$_SESSION['session_user_ip'] = getNormalizedIP($_SERVER['REMOTE_ADDR']);
$_SESSION['session_user_level'] = 0;
$_SESSION['session_user_firstname'] = '';
$_SESSION['session_user_lastname'] = '';
$_SESSION['session_test_login'] = '';
// read client cookie
if (isset($_COOKIE['LastVisit'])) {
$_SESSION['session_last_visit'] = intval($_COOKIE['LastVisit']);
} else {
$_SESSION['session_last_visit'] = 0;
}
// set client cookie 设置用户客户端cookie
$cookie_now_time = time(); // note: while time() function returns a 32 bit integer, it works fine until year 2038.
$cookie_expire_time = $cookie_now_time + K_COOKIE_EXPIRE; //cookie有效期
setcookie('LastVisit', $cookie_now_time, $cookie_expire_time, K_COOKIE_PATH, K_COOKIE_DOMAIN, K_COOKIE_SECURE);
setcookie('PHPSESSID', $PHPSESSID, $cookie_expire_time, K_COOKIE_PATH, K_COOKIE_DOMAIN, K_COOKIE_SECURE);
if (isset($_REQUEST['logout'])) { //用户注销退出时
$_SESSION['logout'] = true;
if (strlen(K_LOGOUT_URL) > 0) {
$htmlredir = '<'.'?xml version="1.0" encoding="'.$l['a_meta_charset'].'"?'.'>'.K_NEWLINE;
$htmlredir .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">'.K_NEWLINE;
$htmlredir .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$l['a_meta_language'].'" lang="'.$l['a_meta_language'].'" dir="'.$l['a_meta_dir'].'">'.K_NEWLINE;
$htmlredir .= '<head>'.K_NEWLINE;
$htmlredir .= '<title>LOGOUT</title>'.K_NEWLINE;
$htmlredir .= '<meta http-equiv="refresh" content="0;url='.K_LOGOUT_URL.'" />'.K_NEWLINE;
$htmlredir .= '</head>'.K_NEWLINE;
$htmlredir .= '<body>'.K_NEWLINE;
$htmlredir .= '<a href="'.K_LOGOUT_URL.'">LOGOUT...</a>'.K_NEWLINE;
$htmlredir .= '</body>'.K_NEWLINE;
$htmlredir .= '</html>'.K_NEWLINE;
header('Location: '.K_LOGOUT_URL);
echo $htmlredir;
exit;
}
}
}
}
else {
F_display_db_error();
}
// 用户登录
require_once('../../shared/code/tce_altauth.php');
$altusr = F_altLogin(); //直接输入账号密码 进入:5) RADIUS里面==>如果用户提交的账号密码正确,返回此用户信息,数组形式。
if(isset($_POST['logaction']) AND ($_POST['logaction'] == 'login') AND isset($_POST['xuser_name']) AND isset($_POST['xuser_password'])) { //如果登录框已点击提交
// check login attempt from the current client device to avoid brute force attack
$bruteforce = true;
$fingerprintkey = md5(getClientFingerprint());
$sqlt = 'SELECT * FROM '.K_TABLE_SESSIONS.' WHERE cpsession_id=\''.$fingerprintkey.'\' LIMIT 1';
if($rt = F_db_query($sqlt, $db)){
if($mt = F_db_fetch_array($rt)) {
if (strtotime($mt['cpsession_expiry']) < time()) { //检查用户活动session有效期
$bruteforce = false;
}
$wait = intval($mt['cpsession_data']);
if ($wait < K_SECONDS_IN_HOUR) {
$wait *= K_BRUTE_FORCE_DELAY_RATIO;
}
$sqlup = 'UPDATE '.K_TABLE_SESSIONS.' SET
cpsession_expiry=\''.date(K_TIMESTAMP_FORMAT, (time() + $wait)).'\',
cpsession_data=\''.$wait.'\'
WHERE cpsession_id=\''.$fingerprintkey.'\'';
if (!F_db_query($sqlup, $db)) {
F_display_db_error();
}
}
else {
$wait = 1; //要等待的秒数
$sqls = 'INSERT INTO '.K_TABLE_SESSIONS.' (
cpsession_id,
cpsession_expiry,
cpsession_data
) VALUES (
\''.$fingerprintkey.'\',
\''.date(K_TIMESTAMP_FORMAT, (time() + $wait)).'\',
\''.$wait.'\'
)';
if (!F_db_query($sqls, $db)) {
F_display_db_error();
}
$bruteforce = false;
}
}
if($bruteforce) {
F_print_error('WARNING', $l['m_login_brute_force'].' '.$wait);
}
else{
$xuser_password = getPasswordHash($_POST['xuser_password']); //对用户输入密码进行编码
$otp = false;
if(K_OTP_LOGIN){ //如果这里K_OTP_LOGIN设置为true,就表示需要用密码进行一次登录验证
$mtime = microtime(true);
if ((isset($_POST['xuser_otpcode'])) AND !empty($_POST['xuser_otpcode'])
AND (($_POST['xuser_otpcode'] == F_getOTP($m['user_otpkey'], $mtime))
OR ($_POST['xuser_otpcode'] == F_getOTP($m['user_otpkey'], ($mtime - 30)))
OR ($_POST['xuser_otpcode'] == F_getOTP($m['user_otpkey'], ($mtime + 30))))) {
// check if this OTP token has been alredy used
$sqlt = 'SELECT cpsession_id FROM '.K_TABLE_SESSIONS.' WHERE cpsession_id=\''.$_POST['xuser_otpcode'].'\' LIMIT 1';
if ($rt = F_db_query($sqlt, $db)) {
if (!F_db_fetch_array($rt)) {
// Store this token on the session table to mark it as invalid for 5 minute (300 seconds)
$sqltu = 'INSERT INTO '.K_TABLE_SESSIONS.' (
cpsession_id,
cpsession_expiry,
cpsession_data
) VALUES (
\''.$_POST['xuser_otpcode'].'\',
\''.date(K_TIMESTAMP_FORMAT, (time() + 300)).'\',
\'300\'
)';
if (!F_db_query($sqltu, $db)) {
F_display_db_error();
}
$otp = true;
}
}
}
}
if(!K_OTP_LOGIN OR $otp){ //验证提交数据是否正确
$sql = 'SELECT * FROM '.K_TABLE_USERS.' WHERE user_name=\''.F_escape_sql($_POST['xuser_name']).'\' AND user_password=\''.$xuser_password.'\'';
if($r = F_db_query($sql, $db)){
if ($m = F_db_fetch_array($r)) { //输入正确
$_SESSION['session_user_id'] = $m['user_id'];
$_SESSION['session_user_name'] = $m['user_name'];
$_SESSION['session_user_ip'] = getNormalizedIP($_SERVER['REMOTE_ADDR']);
$_SESSION['session_user_level'] = $m['user_level'];
$_SESSION['session_user_firstname'] = urlencode($m['user_firstname']);
$_SESSION['session_user_lastname'] = urlencode($m['user_lastname']);
$_SESSION['session_test_login'] = '';
if (isset($_COOKIE['LastVisit'])) {
$_SESSION['session_last_visit'] = intval($_COOKIE['LastVisit']);
} else {
$_SESSION['session_last_visit'] = 0;
}
$logged = true;
if (K_USER_GROUP_RSYNC AND ($altusr !== false)){
F_syncUserGroups($_SESSION['session_user_id'], $altusr['usrgrp_group_id']); //同步用户的用户组
}
}
elseif(!F_check_unique(K_TABLE_USERS, 'user_name=\''.F_escape_sql($_POST['xuser_name']).'\'')){ //用户名存在但密码错误
if($altusr !== false){ //这里已经验证返回正确的,但是密码不一样,那就同步更新下密码
$sqlu = 'UPDATE '.K_TABLE_USERS.' SET
user_password=\''.$xuser_password.'\'
WHERE user_name=\''.F_escape_sql($_POST['xuser_name']).'\'';
if(!$ru = F_db_query($sqlu, $db)){
F_display_db_error();
}
$sqld = 'SELECT * FROM '.K_TABLE_USERS.' WHERE user_name=\''.F_escape_sql($_POST['xuser_name']).'\' AND user_password=\''.$xuser_password.'\'';
if ($rd = F_db_query($sqld, $db)) { //重新获取用户信息,并设置session
if ($md = F_db_fetch_array($rd)) {
$_SESSION['session_user_id'] = $md['user_id'];
$_SESSION['session_user_name'] = $md['user_name'];
$_SESSION['session_user_ip'] = getNormalizedIP($_SERVER['REMOTE_ADDR']);
$_SESSION['session_user_level'] = $md['user_level'];
$_SESSION['session_user_firstname'] = urlencode($md['user_firstname']);
$_SESSION['session_user_lastname'] = urlencode($md['user_lastname']);
$_SESSION['session_last_visit'] = 0;
$_SESSION['session_test_login'] = '';
$logged = true;
if(K_USER_GROUP_RSYNC){
F_syncUserGroups($_SESSION['session_user_id'], $altusr['usrgrp_group_id']);
}
}
} else {
F_display_db_error();
}
}
else{
F_print_error('WARNING', $l['m_login_wrong']); //提交数据有误,登录验证失败
}
}
else {
// this user do not exist on TCExam database
if ($altusr !== false) {
// replicate external user account on TCExam local database
$sql = 'INSERT INTO '.K_TABLE_USERS.' (
user_regdate,
user_ip,
user_name,
user_email,
user_password,
user_regnumber,
user_firstname,
user_lastname,
user_birthdate,
user_birthplace,
user_ssn,
user_level
) VALUES (
\''.F_escape_sql(date(K_TIMESTAMP_FORMAT)).'\',
\''.F_escape_sql(getNormalizedIP($_SERVER['REMOTE_ADDR'])).'\',
\''.F_escape_sql($_POST['xuser_name']).'\',
'.F_empty_to_null($altusr['user_email']).',
\''.getPasswordHash($_POST['xuser_password']).'\',
'.F_empty_to_null($altusr['user_regnumber']).',
'.F_empty_to_null($altusr['user_firstname']).',
'.F_empty_to_null($altusr['user_lastname']).',
'.F_empty_to_null($altusr['user_birthdate']).',
'.F_empty_to_null($altusr['user_birthplace']).',
'.F_empty_to_null($altusr['user_ssn']).',
\''.intval($altusr['user_level']).'\'
)';
if (!$r = F_db_query($sql, $db)) {
F_display_db_error();
} else {
$user_id = F_db_insert_id($db, K_TABLE_USERS, 'user_id');
// sets some user's session data
$_SESSION['session_user_id'] = $user_id;
$_SESSION['session_user_name'] = F_escape_sql($_POST['xuser_name']);
$_SESSION['session_user_ip'] = getNormalizedIP($_SERVER['REMOTE_ADDR']);
$_SESSION['session_user_level'] = intval($altusr['user_level']);
$_SESSION['session_user_firstname'] = urlencode($altusr['user_firstname']);
$_SESSION['session_user_lastname'] = urlencode($altusr['user_lastname']);
$_SESSION['session_last_visit'] = 0;
$_SESSION['session_test_login'] = '';
$logged = true;
// sync user groups
F_syncUserGroups($_SESSION['session_user_id'], $altusr['usrgrp_group_id']);
}
}
else {
$login_error = true;
}
}
}
else {
F_display_db_error(); //验证提交数据错误
}
}
else {
$login_error = true;
}
}
}
if(!isset($pagelevel)){
$pagelevel = 0; //设置首页的默认级别
}
if ($pagelevel) {
if ($_SESSION['session_user_level'] < $pagelevel){ //检查用户级别
F_login_form(); //【【【【【【【【【【【【【显示登录页面】】】】】】】】】】】】首先进入这里显示
}
}
if($logged){ //如果用户只是登录,重新加载页面
$htmlredir = '<'.'?xml version="1.0" encoding="'.$l['a_meta_charset'].'"?'.'>'.K_NEWLINE;
$htmlredir .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.K_NEWLINE;
$htmlredir .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$l['a_meta_language'].'" lang="'.$l['a_meta_language'].'" dir="'.$l['a_meta_dir'].'">'.K_NEWLINE;
$htmlredir .= '<head>'.K_NEWLINE;
$htmlredir .= '<title>ENTER</title>'.K_NEWLINE;
$htmlredir .= '<meta http-equiv="refresh" content="0" />'.K_NEWLINE; //reload page
$htmlredir .= '</head>'.K_NEWLINE;
$htmlredir .= '<body>'.K_NEWLINE;
$htmlredir .= '<a href="'.$_SERVER['SCRIPT_NAME'].'">ENTER</a>'.K_NEWLINE;
$htmlredir .= '</body>'.K_NEWLINE;
$htmlredir .= '</html>'.K_NEWLINE;
switch (K_REDIRECT_LOGIN_MODE) {
case 1: {
// relative redirect
header('Location: '.$_SERVER['SCRIPT_NAME']);
break;
}
case 2: {
// absolute redirect
header('Location: '.K_PATH_HOST.$_SERVER['SCRIPT_NAME']);
break;
}
case 3: {
// html redirect
echo $htmlredir;
break;
}
case 4:
default: {
// full redirect
header('Location: '.K_PATH_HOST.$_SERVER['SCRIPT_NAME']);
echo $htmlredir;
break;
}
}
exit;
}
if (isset($_POST['testpswaction']) AND ($_POST['testpswaction'] == 'login') AND isset($_POST['xtest_password']) AND isset($_POST['testid'])) {
require_once('../../shared/code/tce_functions_test.php');
$tph = F_getTestPassword($_POST['testid']);
if(getPasswordHash($_POST['xtest_password']) == $tph) {
// test password is correct, save status on a session variable
$_SESSION['session_test_login'] = getPasswordHash($tph.$_POST['testid'].$_SESSION['session_user_id'].$_SESSION['session_user_ip']);
}
else{
F_print_error('WARNING', $l['m_wrong_test_password']);
}
}
转载于:https://blog.51cto.com/xuqin/1205721