328 lines
10 KiB
PHP
328 lines
10 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* [Discuz!] (C)2001-2099 Comsenz Inc.
|
||
|
* This is NOT a freeware, use is subject to license terms
|
||
|
*
|
||
|
* $Id: function_seccode.php 33661 2013-07-29 08:18:34Z nemohou $
|
||
|
*/
|
||
|
|
||
|
if(!defined('IN_DISCUZ')) {
|
||
|
exit('Access Denied');
|
||
|
}
|
||
|
|
||
|
class helper_seccheck {
|
||
|
|
||
|
private function _check($type) {
|
||
|
global $_G;
|
||
|
if(!isset($_G['cookie']['sec'.$type])) {
|
||
|
return false;
|
||
|
}
|
||
|
list($ssid, $sign) = explode('.', $_G['cookie']['sec'.$type]);
|
||
|
if($sign != substr(md5($ssid.$_G['uid'].$_G['authkey']), 8, 18)) {
|
||
|
return false;
|
||
|
}
|
||
|
$seccheck = C::t('common_seccheck')->fetch($ssid);
|
||
|
if(!$seccheck) {
|
||
|
return false;
|
||
|
}
|
||
|
if(TIMESTAMP - $seccheck['dateline'] > 600 || $seccheck['verified'] > 4) {
|
||
|
C::t('common_seccheck')->delete_expiration($ssid);
|
||
|
return false;
|
||
|
}
|
||
|
return $seccheck;
|
||
|
}
|
||
|
|
||
|
function _create($type, $code = '') {
|
||
|
global $_G;
|
||
|
$ssid = C::t('common_seccheck')->insert(array(
|
||
|
'dateline' => TIMESTAMP,
|
||
|
'code' => $code,
|
||
|
'succeed' => 0,
|
||
|
'verified' => 0,
|
||
|
), true);
|
||
|
dsetcookie('sec'.$type, $ssid.'.'.substr(md5($ssid.$_G['uid'].$_G['authkey']), 8, 18));
|
||
|
}
|
||
|
|
||
|
public static function make_seccode($seccode = ''){
|
||
|
global $_G;
|
||
|
if(!$seccode) {
|
||
|
$seccode = random(6, 1);
|
||
|
$seccodeunits = '';
|
||
|
if($_G['setting']['seccodedata']['type'] == 1) {
|
||
|
$lang = lang('seccode');
|
||
|
$len = strtoupper(CHARSET) == 'GBK' ? 2 : 3;
|
||
|
$code = array(substr($seccode, 0, 3), substr($seccode, 3, 3));
|
||
|
$seccode = '';
|
||
|
for($i = 0; $i < 2; $i++) {
|
||
|
$seccode .= substr($lang['chn'], $code[$i] * $len, $len);
|
||
|
}
|
||
|
} elseif($_G['setting']['seccodedata']['type'] == 3) {
|
||
|
$s = sprintf('%04s', base_convert($seccode, 10, 20));
|
||
|
$seccodeunits = 'CEFHKLMNOPQRSTUVWXYZ';
|
||
|
} else {
|
||
|
$s = sprintf('%04s', base_convert($seccode, 10, 24));
|
||
|
$seccodeunits = 'BCEFGHJKMPQRTVWXY2346789';
|
||
|
}
|
||
|
if($seccodeunits) {
|
||
|
$seccode = '';
|
||
|
for($i = 0; $i < 4; $i++) {
|
||
|
$unit = ord($s{$i});
|
||
|
$seccode .= ($unit >= 0x30 && $unit <= 0x39) ? $seccodeunits[$unit - 0x30] : $seccodeunits[$unit - 0x57];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
self::_create('code', $seccode);
|
||
|
return $seccode;
|
||
|
}
|
||
|
|
||
|
public static function make_secqaa() {
|
||
|
global $_G;
|
||
|
loadcache('secqaa');
|
||
|
$secqaakey = max(1, random(1, 1));
|
||
|
if($_G['cache']['secqaa'][$secqaakey]['type']) {
|
||
|
$etype = explode(':', $_G['cache']['secqaa'][$secqaakey]['question']);
|
||
|
if(count($etype) > 1) {
|
||
|
if(!preg_match('/^\w+$/', $etype[0]) || !preg_match('/^\w+$/', $etype[1])) {
|
||
|
return;
|
||
|
}
|
||
|
$qaafile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/secqaa/secqaa_'.$etype[1].'.php';
|
||
|
$class = $etype[1];
|
||
|
} else {
|
||
|
if(!preg_match('/^\w+$/', $_G['cache']['secqaa'][$secqaakey]['question'])) {
|
||
|
return;
|
||
|
}
|
||
|
$qaafile = libfile('secqaa/'.$_G['cache']['secqaa'][$secqaakey]['question'], 'class');
|
||
|
$class = $_G['cache']['secqaa'][$secqaakey]['question'];
|
||
|
}
|
||
|
if(file_exists($qaafile)) {
|
||
|
@include_once $qaafile;
|
||
|
$class = 'secqaa_'.$class;
|
||
|
if(class_exists($class)) {
|
||
|
$qaa = new $class();
|
||
|
if(method_exists($qaa, 'make')) {
|
||
|
$_G['cache']['secqaa'][$secqaakey]['answer'] = md5($qaa->make($_G['cache']['secqaa'][$secqaakey]['question']));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
self::_create('qaa', substr($_G['cache']['secqaa'][$secqaakey]['answer'], 0, 6));
|
||
|
return $_G['cache']['secqaa'][$secqaakey]['question'];
|
||
|
}
|
||
|
|
||
|
public static function check_seccode($value, $idhash, $fromjs = 0, $modid = '') {
|
||
|
global $_G;
|
||
|
if(!$_G['setting']['seccodestatus']) {
|
||
|
return true;
|
||
|
}
|
||
|
$seccheck = self::_check('code');
|
||
|
if(!$seccheck) {
|
||
|
return false;
|
||
|
}
|
||
|
$ssid = $seccheck['ssid'];
|
||
|
if(!is_numeric($_G['setting']['seccodedata']['type'])) {
|
||
|
$etype = explode(':', $_G['setting']['seccodedata']['type']);
|
||
|
if(count($etype) > 1) {
|
||
|
if(!preg_match('/^\w+$/', $etype[0]) || !preg_match('/^\w+$/', $etype[1])) {
|
||
|
return false;
|
||
|
}
|
||
|
$codefile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/seccode/seccode_'.$etype[1].'.php';
|
||
|
$class = $etype[1];
|
||
|
} else {
|
||
|
if(!preg_match('/^\w+$/', $_G['setting']['seccodedata']['type'])) {
|
||
|
return false;
|
||
|
}
|
||
|
$codefile = libfile('seccode/'.$_G['setting']['seccodedata']['type'], 'class');
|
||
|
$class = $_G['setting']['seccodedata']['type'];
|
||
|
}
|
||
|
if(file_exists($codefile)) {
|
||
|
@include_once $codefile;
|
||
|
$class = 'seccode_'.$class;
|
||
|
if(class_exists($class)) {
|
||
|
$code = new $class();
|
||
|
if(method_exists($code, 'check')) {
|
||
|
$return = $code->check($value, $idhash, $seccheck, $fromjs, $modid);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
$return = false;
|
||
|
}
|
||
|
} else {
|
||
|
$return = $seccheck['code'] == strtoupper($value);
|
||
|
}
|
||
|
if($return) {
|
||
|
C::t('common_seccheck')->update_succeed($ssid);
|
||
|
} else {
|
||
|
C::t('common_seccheck')->update_verified($ssid);
|
||
|
}
|
||
|
return $return;
|
||
|
}
|
||
|
|
||
|
public static function check_secqaa($value, $idhash) {
|
||
|
global $_G;
|
||
|
if(!$_G['setting']['secqaa']) {
|
||
|
return true;
|
||
|
}
|
||
|
$seccheck = self::_check('qaa');
|
||
|
if(!$seccheck) {
|
||
|
return false;
|
||
|
}
|
||
|
$ssid = $seccheck['ssid'];
|
||
|
$return = $seccheck['code'] == substr(md5($value), 0, 6);
|
||
|
if($return) {
|
||
|
C::t('common_seccheck')->update_succeed($ssid);
|
||
|
} else {
|
||
|
C::t('common_seccheck')->update_verified($ssid);
|
||
|
}
|
||
|
return $return;
|
||
|
}
|
||
|
|
||
|
public static function rule_register() {
|
||
|
global $_G;
|
||
|
$seccheckrule = & $_G['setting']['seccodedata']['rule']['register'];
|
||
|
if($seccheckrule['allow'] == 1) {
|
||
|
$seccode = true;
|
||
|
} elseif($seccheckrule['allow'] == 2) {
|
||
|
if($seccheckrule['numlimit'] > 0) {
|
||
|
loadcache('seccodedata', true);
|
||
|
if($_G['cache']['seccodedata']['register']['show']) {
|
||
|
$seccode = true;
|
||
|
} else {
|
||
|
$regnumber = C::t('common_member')->count_by_regdate(TIMESTAMP - $seccheckrule['timelimit']);
|
||
|
if($regnumber >= $seccheckrule['numlimit']) {
|
||
|
$seccode = true;
|
||
|
$_G['cache']['seccodedata']['register']['show'] = 1;
|
||
|
savecache('seccodedata', $_G['cache']['seccodedata']);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
$seccode = false;
|
||
|
}
|
||
|
return array(
|
||
|
$seccode,
|
||
|
$_G['setting']['secqaa']['status'] & 1
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static function rule_login() {
|
||
|
global $_G;
|
||
|
$seccheckrule = & $_G['setting']['seccodedata']['rule']['login'];
|
||
|
if($seccheckrule['allow'] == 1) {
|
||
|
$seccode = true;
|
||
|
} elseif($seccheckrule['allow'] == 2) {
|
||
|
$seccode = false;
|
||
|
} else {
|
||
|
$seccode = false;
|
||
|
}
|
||
|
return array($seccode);
|
||
|
}
|
||
|
|
||
|
public static function rule_post($action) {
|
||
|
global $_G;
|
||
|
$seccheckrule = & $_G['setting']['seccodedata']['rule']['post'];
|
||
|
if($seccheckrule['allow'] == 1) {
|
||
|
$seccode = !$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts'];
|
||
|
} elseif($seccheckrule['allow'] == 2) {
|
||
|
if(C::t('common_member_secwhite')->check($_G['uid'])) {
|
||
|
$seccode = false;
|
||
|
} else {
|
||
|
$seccode = getuserprofile('posts') < $_G['setting']['seccodedata']['minposts'];
|
||
|
if(!$seccode && $seccheckrule['numlimit']) {
|
||
|
$count = C::t('forum_post')->count_by_search('pid:0', null, null, null, null, $_G['uid'], null, TIMESTAMP - $seccheckrule['timelimit']);
|
||
|
$seccode = $seccheckrule['numlimit'] <= $count;
|
||
|
}
|
||
|
if($action == 'newthread' && !$seccode && !empty($_POST) && $seccheckrule['nplimit']) {
|
||
|
if(!$_G['cookie']['st_t']) {
|
||
|
$seccode = true;
|
||
|
} else {
|
||
|
list($uid, $t, $hash) = explode('|', $_G['cookie']['st_t']);
|
||
|
list($t, $m) = explode(',', $t);
|
||
|
if(md5($uid.'|'.$t.$_G['config']['security']['authkey']) == $hash && !$m) {
|
||
|
if(TIMESTAMP - $t <= $seccheckrule['nplimit']) {
|
||
|
$seccode = true;
|
||
|
} else {
|
||
|
$seccode = false;
|
||
|
}
|
||
|
} else {
|
||
|
$seccode = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if($action == 'reply' && !$seccode && !empty($_POST) && $seccheckrule['vplimit']) {
|
||
|
if(!$_G['cookie']['st_p']) {
|
||
|
$seccode = true;
|
||
|
} else {
|
||
|
list($uid, $t, $hash) = explode('|', $_G['cookie']['st_p']);
|
||
|
list($t, $m) = explode(',', $t);
|
||
|
if(md5($uid.'|'.$t.$_G['config']['security']['authkey']) == $hash && !$m) {
|
||
|
if(TIMESTAMP - $t <= $seccheckrule['vplimit']) {
|
||
|
$seccode = true;
|
||
|
} else {
|
||
|
$seccode = false;
|
||
|
}
|
||
|
} else {
|
||
|
$seccode = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
$seccode = false;
|
||
|
}
|
||
|
return array(
|
||
|
$seccode,
|
||
|
$_G['setting']['secqaa']['status'] & 2 && (!$_G['setting']['secqaa']['minposts'] || getuserprofile('posts') < $_G['setting']['secqaa']['minposts'])
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static function rule_publish($rule) {
|
||
|
global $_G;
|
||
|
$seccheckrule = & $_G['setting']['seccodedata']['rule']['post'];
|
||
|
return array(
|
||
|
$seccheckrule['allow'] && (!$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts']),
|
||
|
$_G['setting']['secqaa']['status'] & 2 && (!$_G['setting']['secqaa']['minposts'] || getuserprofile('posts') < $_G['setting']['secqaa']['minposts'])
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static function rule_password($rule) {
|
||
|
global $_G;
|
||
|
$seccheckrule = & $_G['setting']['seccodedata']['rule']['password'];
|
||
|
return array(
|
||
|
$seccheckrule['allow'] && (!$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts']),
|
||
|
$_G['setting']['secqaa']['status'] & 4 && (!$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts'])
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static function rule_card() {
|
||
|
global $_G;
|
||
|
$seccheckrule = & $_G['setting']['seccodedata']['rule']['card'];
|
||
|
return array($seccheckrule['allow']);
|
||
|
}
|
||
|
|
||
|
public static function seccheck($rule, $param = array()) {
|
||
|
global $_G;
|
||
|
if($_G['uid'] && !checkperm('seccode')) {
|
||
|
return array();
|
||
|
}
|
||
|
if(method_exists('helper_seccheck', 'rule_'.$rule)) {
|
||
|
$return = call_user_func(array('helper_seccheck', 'rule_'.$rule), $param);
|
||
|
if(!isset($_G['cookie']['seccloud'])) {
|
||
|
if($_G['setting']['seccodedata']['cloudip'] && !$return[0]) {
|
||
|
$return[0] = captcha::isneed();
|
||
|
if($return[0]) {
|
||
|
dsetcookie('seccloud', 1);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
$return[0] = true;
|
||
|
}
|
||
|
return $return;
|
||
|
} else {
|
||
|
return array();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
?>
|