helper_seccheck.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: function_seccode.php 33661 2013-07-29 08:18:34Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. class helper_seccheck {
  12. private function _check($type) {
  13. global $_G;
  14. if(!isset($_G['cookie']['sec'.$type])) {
  15. return false;
  16. }
  17. list($ssid, $sign) = explode('.', $_G['cookie']['sec'.$type]);
  18. if($sign != substr(md5($ssid.$_G['uid'].$_G['authkey']), 8, 18)) {
  19. return false;
  20. }
  21. $seccheck = C::t('common_seccheck')->fetch($ssid);
  22. if(!$seccheck) {
  23. return false;
  24. }
  25. if(TIMESTAMP - $seccheck['dateline'] > 600 || $seccheck['verified'] > 4) {
  26. C::t('common_seccheck')->delete_expiration($ssid);
  27. return false;
  28. }
  29. return $seccheck;
  30. }
  31. function _create($type, $code = '') {
  32. global $_G;
  33. $ssid = C::t('common_seccheck')->insert(array(
  34. 'dateline' => TIMESTAMP,
  35. 'code' => $code,
  36. 'succeed' => 0,
  37. 'verified' => 0,
  38. ), true);
  39. dsetcookie('sec'.$type, $ssid.'.'.substr(md5($ssid.$_G['uid'].$_G['authkey']), 8, 18));
  40. }
  41. public static function make_seccode($seccode = ''){
  42. global $_G;
  43. if(!$seccode) {
  44. $seccode = random(6, 1);
  45. $seccodeunits = '';
  46. if($_G['setting']['seccodedata']['type'] == 1) {
  47. $lang = lang('seccode');
  48. $len = strtoupper(CHARSET) == 'GBK' ? 2 : 3;
  49. $code = array(substr($seccode, 0, 3), substr($seccode, 3, 3));
  50. $seccode = '';
  51. for($i = 0; $i < 2; $i++) {
  52. $seccode .= substr($lang['chn'], $code[$i] * $len, $len);
  53. }
  54. } elseif($_G['setting']['seccodedata']['type'] == 3) {
  55. $s = sprintf('%04s', base_convert($seccode, 10, 20));
  56. $seccodeunits = 'CEFHKLMNOPQRSTUVWXYZ';
  57. } else {
  58. $s = sprintf('%04s', base_convert($seccode, 10, 24));
  59. $seccodeunits = 'BCEFGHJKMPQRTVWXY2346789';
  60. }
  61. if($seccodeunits) {
  62. $seccode = '';
  63. for($i = 0; $i < 4; $i++) {
  64. $unit = ord($s{$i});
  65. $seccode .= ($unit >= 0x30 && $unit <= 0x39) ? $seccodeunits[$unit - 0x30] : $seccodeunits[$unit - 0x57];
  66. }
  67. }
  68. }
  69. self::_create('code', $seccode);
  70. return $seccode;
  71. }
  72. public static function make_secqaa() {
  73. global $_G;
  74. loadcache('secqaa');
  75. $secqaakey = max(1, random(1, 1));
  76. if($_G['cache']['secqaa'][$secqaakey]['type']) {
  77. $etype = explode(':', $_G['cache']['secqaa'][$secqaakey]['question']);
  78. if(count($etype) > 1) {
  79. if(!preg_match('/^\w+$/', $etype[0]) || !preg_match('/^\w+$/', $etype[1])) {
  80. return;
  81. }
  82. $qaafile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/secqaa/secqaa_'.$etype[1].'.php';
  83. $class = $etype[1];
  84. } else {
  85. if(!preg_match('/^\w+$/', $_G['cache']['secqaa'][$secqaakey]['question'])) {
  86. return;
  87. }
  88. $qaafile = libfile('secqaa/'.$_G['cache']['secqaa'][$secqaakey]['question'], 'class');
  89. $class = $_G['cache']['secqaa'][$secqaakey]['question'];
  90. }
  91. if(file_exists($qaafile)) {
  92. @include_once $qaafile;
  93. $class = 'secqaa_'.$class;
  94. if(class_exists($class)) {
  95. $qaa = new $class();
  96. if(method_exists($qaa, 'make')) {
  97. $_G['cache']['secqaa'][$secqaakey]['answer'] = md5($qaa->make($_G['cache']['secqaa'][$secqaakey]['question']));
  98. }
  99. }
  100. }
  101. }
  102. self::_create('qaa', substr($_G['cache']['secqaa'][$secqaakey]['answer'], 0, 6));
  103. return $_G['cache']['secqaa'][$secqaakey]['question'];
  104. }
  105. public static function check_seccode($value, $idhash, $fromjs = 0, $modid = '') {
  106. global $_G;
  107. if(!$_G['setting']['seccodestatus']) {
  108. return true;
  109. }
  110. $seccheck = self::_check('code');
  111. if(!$seccheck) {
  112. return false;
  113. }
  114. $ssid = $seccheck['ssid'];
  115. if(!is_numeric($_G['setting']['seccodedata']['type'])) {
  116. $etype = explode(':', $_G['setting']['seccodedata']['type']);
  117. if(count($etype) > 1) {
  118. if(!preg_match('/^\w+$/', $etype[0]) || !preg_match('/^\w+$/', $etype[1])) {
  119. return false;
  120. }
  121. $codefile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/seccode/seccode_'.$etype[1].'.php';
  122. $class = $etype[1];
  123. } else {
  124. if(!preg_match('/^\w+$/', $_G['setting']['seccodedata']['type'])) {
  125. return false;
  126. }
  127. $codefile = libfile('seccode/'.$_G['setting']['seccodedata']['type'], 'class');
  128. $class = $_G['setting']['seccodedata']['type'];
  129. }
  130. if(file_exists($codefile)) {
  131. @include_once $codefile;
  132. $class = 'seccode_'.$class;
  133. if(class_exists($class)) {
  134. $code = new $class();
  135. if(method_exists($code, 'check')) {
  136. $return = $code->check($value, $idhash, $seccheck, $fromjs, $modid);
  137. }
  138. }
  139. } else {
  140. $return = false;
  141. }
  142. } else {
  143. $return = $seccheck['code'] == strtoupper($value);
  144. }
  145. if($return) {
  146. C::t('common_seccheck')->update_succeed($ssid);
  147. } else {
  148. C::t('common_seccheck')->update_verified($ssid);
  149. }
  150. return $return;
  151. }
  152. public static function check_secqaa($value, $idhash) {
  153. global $_G;
  154. if(!$_G['setting']['secqaa']) {
  155. return true;
  156. }
  157. $seccheck = self::_check('qaa');
  158. if(!$seccheck) {
  159. return false;
  160. }
  161. $ssid = $seccheck['ssid'];
  162. $return = $seccheck['code'] == substr(md5($value), 0, 6);
  163. if($return) {
  164. C::t('common_seccheck')->update_succeed($ssid);
  165. } else {
  166. C::t('common_seccheck')->update_verified($ssid);
  167. }
  168. return $return;
  169. }
  170. public static function rule_register() {
  171. global $_G;
  172. $seccheckrule = & $_G['setting']['seccodedata']['rule']['register'];
  173. if($seccheckrule['allow'] == 1) {
  174. $seccode = true;
  175. } elseif($seccheckrule['allow'] == 2) {
  176. if($seccheckrule['numlimit'] > 0) {
  177. loadcache('seccodedata', true);
  178. if($_G['cache']['seccodedata']['register']['show']) {
  179. $seccode = true;
  180. } else {
  181. $regnumber = C::t('common_member')->count_by_regdate(TIMESTAMP - $seccheckrule['timelimit']);
  182. if($regnumber >= $seccheckrule['numlimit']) {
  183. $seccode = true;
  184. $_G['cache']['seccodedata']['register']['show'] = 1;
  185. savecache('seccodedata', $_G['cache']['seccodedata']);
  186. }
  187. }
  188. }
  189. } else {
  190. $seccode = false;
  191. }
  192. return array(
  193. $seccode,
  194. $_G['setting']['secqaa']['status'] & 1
  195. );
  196. }
  197. public static function rule_login() {
  198. global $_G;
  199. $seccheckrule = & $_G['setting']['seccodedata']['rule']['login'];
  200. if($seccheckrule['allow'] == 1) {
  201. $seccode = true;
  202. } elseif($seccheckrule['allow'] == 2) {
  203. $seccode = false;
  204. } else {
  205. $seccode = false;
  206. }
  207. return array($seccode);
  208. }
  209. public static function rule_post($action) {
  210. global $_G;
  211. $seccheckrule = & $_G['setting']['seccodedata']['rule']['post'];
  212. if($seccheckrule['allow'] == 1) {
  213. $seccode = !$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts'];
  214. } elseif($seccheckrule['allow'] == 2) {
  215. if(C::t('common_member_secwhite')->check($_G['uid'])) {
  216. $seccode = false;
  217. } else {
  218. $seccode = getuserprofile('posts') < $_G['setting']['seccodedata']['minposts'];
  219. if(!$seccode && $seccheckrule['numlimit']) {
  220. $count = C::t('forum_post')->count_by_search('pid:0', null, null, null, null, $_G['uid'], null, TIMESTAMP - $seccheckrule['timelimit']);
  221. $seccode = $seccheckrule['numlimit'] <= $count;
  222. }
  223. if($action == 'newthread' && !$seccode && !empty($_POST) && $seccheckrule['nplimit']) {
  224. if(!$_G['cookie']['st_t']) {
  225. $seccode = true;
  226. } else {
  227. list($uid, $t, $hash) = explode('|', $_G['cookie']['st_t']);
  228. list($t, $m) = explode(',', $t);
  229. if(md5($uid.'|'.$t.$_G['config']['security']['authkey']) == $hash && !$m) {
  230. if(TIMESTAMP - $t <= $seccheckrule['nplimit']) {
  231. $seccode = true;
  232. } else {
  233. $seccode = false;
  234. }
  235. } else {
  236. $seccode = true;
  237. }
  238. }
  239. }
  240. if($action == 'reply' && !$seccode && !empty($_POST) && $seccheckrule['vplimit']) {
  241. if(!$_G['cookie']['st_p']) {
  242. $seccode = true;
  243. } else {
  244. list($uid, $t, $hash) = explode('|', $_G['cookie']['st_p']);
  245. list($t, $m) = explode(',', $t);
  246. if(md5($uid.'|'.$t.$_G['config']['security']['authkey']) == $hash && !$m) {
  247. if(TIMESTAMP - $t <= $seccheckrule['vplimit']) {
  248. $seccode = true;
  249. } else {
  250. $seccode = false;
  251. }
  252. } else {
  253. $seccode = true;
  254. }
  255. }
  256. }
  257. }
  258. } else {
  259. $seccode = false;
  260. }
  261. return array(
  262. $seccode,
  263. $_G['setting']['secqaa']['status'] & 2 && (!$_G['setting']['secqaa']['minposts'] || getuserprofile('posts') < $_G['setting']['secqaa']['minposts'])
  264. );
  265. }
  266. public static function rule_publish($rule) {
  267. global $_G;
  268. $seccheckrule = & $_G['setting']['seccodedata']['rule']['post'];
  269. return array(
  270. $seccheckrule['allow'] && (!$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts']),
  271. $_G['setting']['secqaa']['status'] & 2 && (!$_G['setting']['secqaa']['minposts'] || getuserprofile('posts') < $_G['setting']['secqaa']['minposts'])
  272. );
  273. }
  274. public static function rule_password($rule) {
  275. global $_G;
  276. $seccheckrule = & $_G['setting']['seccodedata']['rule']['password'];
  277. return array(
  278. $seccheckrule['allow'] && (!$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts']),
  279. $_G['setting']['secqaa']['status'] & 4 && (!$_G['setting']['seccodedata']['minposts'] || getuserprofile('posts') < $_G['setting']['seccodedata']['minposts'])
  280. );
  281. }
  282. public static function rule_card() {
  283. global $_G;
  284. $seccheckrule = & $_G['setting']['seccodedata']['rule']['card'];
  285. return array($seccheckrule['allow']);
  286. }
  287. public static function seccheck($rule, $param = array()) {
  288. global $_G;
  289. if($_G['uid'] && !checkperm('seccode')) {
  290. return array();
  291. }
  292. if(method_exists('helper_seccheck', 'rule_'.$rule)) {
  293. $return = call_user_func(array('helper_seccheck', 'rule_'.$rule), $param);
  294. if(!isset($_G['cookie']['seccloud'])) {
  295. if($_G['setting']['seccodedata']['cloudip'] && !$return[0]) {
  296. $return[0] = captcha::isneed();
  297. if($return[0]) {
  298. dsetcookie('seccloud', 1);
  299. }
  300. }
  301. } else {
  302. $return[0] = true;
  303. }
  304. return $return;
  305. } else {
  306. return array();
  307. }
  308. }
  309. }
  310. ?>