| 1: | <?php
|
| 2: |
|
| 3: |
|
| 4: |
|
| 5: | if (!class_exists('XoopsGTicket')) {
|
| 6: |
|
| 7: | |
| 8: | |
| 9: |
|
| 10: | class XoopsGTicket
|
| 11: | {
|
| 12: | public $_errors = array();
|
| 13: | public $_latest_token = '';
|
| 14: | public $messages = array();
|
| 15: |
|
| 16: | |
| 17: | |
| 18: |
|
| 19: | public function __construct()
|
| 20: | {
|
| 21: | global $xoopsConfig;
|
| 22: |
|
| 23: |
|
| 24: | if (defined('XOOPS_ROOT_PATH') && !empty($xoopsConfig['language']) && false === strpos($xoopsConfig['language'], '/')) {
|
| 25: | if (file_exists(dirname(__DIR__) . '/language/' . $xoopsConfig['language'] . '/gticket_messages.phtml')) {
|
| 26: | include dirname(__DIR__) . '/language/' . $xoopsConfig['language'] . '/gticket_messages.phtml';
|
| 27: | }
|
| 28: | }
|
| 29: |
|
| 30: |
|
| 31: | if (empty($this->messages)) {
|
| 32: | $this->messages = array(
|
| 33: | 'err_general' => 'GTicket Error',
|
| 34: | 'err_nostubs' => 'No stubs found',
|
| 35: | 'err_noticket' => 'No ticket found',
|
| 36: | 'err_nopair' => 'No valid ticket-stub pair found',
|
| 37: | 'err_timeout' => 'Time out',
|
| 38: | 'err_areaorref' => 'Invalid area or referer',
|
| 39: | 'fmt_prompt4repost' => 'error(s) found:<br><span style="background-color:red;font-weight:bold;color:white;">%s</span><br>Confirm it.<br>And do you want to post again?',
|
| 40: | 'btn_repost' => 'repost');
|
| 41: | }
|
| 42: | }
|
| 43: |
|
| 44: |
|
| 45: | |
| 46: | |
| 47: | |
| 48: | |
| 49: | |
| 50: | |
| 51: |
|
| 52: | public function getTicketHtml($salt = '', $timeout = 1800, $area = '')
|
| 53: | {
|
| 54: | return '<input type="hidden" name="XOOPS_G_TICKET" value="' . $this->issue($salt, $timeout, $area) . '" />';
|
| 55: | }
|
| 56: |
|
| 57: |
|
| 58: | |
| 59: | |
| 60: | |
| 61: | |
| 62: | |
| 63: | |
| 64: |
|
| 65: | public function getTicketXoopsForm($salt = '', $timeout = 1800, $area = '')
|
| 66: | {
|
| 67: | return new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area));
|
| 68: | }
|
| 69: |
|
| 70: |
|
| 71: | |
| 72: | |
| 73: | |
| 74: | |
| 75: | |
| 76: |
|
| 77: | public function addTicketXoopsFormElement(&$form, $salt = '', $timeout = 1800, $area = '')
|
| 78: | {
|
| 79: | $form->addElement(new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area)));
|
| 80: | }
|
| 81: |
|
| 82: |
|
| 83: | |
| 84: | |
| 85: | |
| 86: | |
| 87: | |
| 88: | |
| 89: |
|
| 90: | public function getTicketArray($salt = '', $timeout = 1800, $area = '')
|
| 91: | {
|
| 92: | return array('XOOPS_G_TICKET' => $this->issue($salt, $timeout, $area));
|
| 93: | }
|
| 94: |
|
| 95: |
|
| 96: | |
| 97: | |
| 98: | |
| 99: | |
| 100: | |
| 101: | |
| 102: | |
| 103: |
|
| 104: | public function getTicketParamString($salt = '', $noamp = false, $timeout = 1800, $area = '')
|
| 105: | {
|
| 106: | return ($noamp ? '' : '&') . 'XOOPS_G_TICKET=' . $this->issue($salt, $timeout, $area);
|
| 107: | }
|
| 108: |
|
| 109: |
|
| 110: | |
| 111: | |
| 112: | |
| 113: | |
| 114: | |
| 115: | |
| 116: |
|
| 117: | public function issue($salt = '', $timeout = 1800, $area = '')
|
| 118: | {
|
| 119: | global $xoopsModule;
|
| 120: |
|
| 121: | if ('' === $salt) {
|
| 122: | $salt = '$2y$07$' . str_replace('+', '.', base64_encode(random_bytes(16)));
|
| 123: | }
|
| 124: |
|
| 125: |
|
| 126: | list($usec, $sec) = explode(' ', microtime());
|
| 127: | $appendix_salt = empty($_SERVER['PATH']) ? XOOPS_DB_NAME : $_SERVER['PATH'];
|
| 128: | $token = crypt($salt . $usec . $appendix_salt . $sec, $salt);
|
| 129: | $this->_latest_token = $token;
|
| 130: |
|
| 131: | if (empty($_SESSION['XOOPS_G_STUBS'])) {
|
| 132: | $_SESSION['XOOPS_G_STUBS'] = array();
|
| 133: | }
|
| 134: |
|
| 135: |
|
| 136: | if (count($_SESSION['XOOPS_G_STUBS']) > 10) {
|
| 137: | $_SESSION['XOOPS_G_STUBS'] = array_slice($_SESSION['XOOPS_G_STUBS'], -10);
|
| 138: | }
|
| 139: |
|
| 140: |
|
| 141: | $referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['REQUEST_URI'];
|
| 142: |
|
| 143: |
|
| 144: | if (!$area && isset($xoopsModule) && is_object($xoopsModule)) {
|
| 145: | $area = $xoopsModule->getVar('dirname');
|
| 146: | }
|
| 147: |
|
| 148: |
|
| 149: | $_SESSION['XOOPS_G_STUBS'][] = array(
|
| 150: | 'expire' => time() + $timeout,
|
| 151: | 'referer' => $referer,
|
| 152: | 'area' => $area,
|
| 153: | 'token' => $token);
|
| 154: |
|
| 155: |
|
| 156: | return md5($token . XOOPS_DB_PREFIX);
|
| 157: | }
|
| 158: |
|
| 159: |
|
| 160: | |
| 161: | |
| 162: | |
| 163: | |
| 164: | |
| 165: | |
| 166: |
|
| 167: | public function check($post = true, $area = '', $allow_repost = true)
|
| 168: | {
|
| 169: | global $xoopsModule;
|
| 170: |
|
| 171: | $this->_errors = array();
|
| 172: |
|
| 173: |
|
| 174: | if (!isset($_SESSION['XOOPS_G_STUBS']) || !is_array($_SESSION['XOOPS_G_STUBS'])) {
|
| 175: | $this->_errors[] = $this->messages['err_nostubs'];
|
| 176: | $_SESSION['XOOPS_G_STUBS'] = array();
|
| 177: | }
|
| 178: |
|
| 179: |
|
| 180: | $ticket = '';
|
| 181: | if ($post) {
|
| 182: | if (isset($_POST['XOOPS_G_TICKET'])) {
|
| 183: | $ticket = $_POST['XOOPS_G_TICKET'];
|
| 184: | }
|
| 185: | } else {
|
| 186: | if (isset($_GET['XOOPS_G_TICKET'])) {
|
| 187: | $ticket = $_GET['XOOPS_G_TICKET'];
|
| 188: | }
|
| 189: | }
|
| 190: |
|
| 191: |
|
| 192: | if (empty($ticket)) {
|
| 193: | $this->_errors[] = $this->messages['err_noticket'];
|
| 194: | }
|
| 195: |
|
| 196: |
|
| 197: | $stubs_tmp = $_SESSION['XOOPS_G_STUBS'];
|
| 198: | $_SESSION['XOOPS_G_STUBS'] = array();
|
| 199: | foreach ($stubs_tmp as $stub) {
|
| 200: |
|
| 201: | if ($stub['expire'] >= time()) {
|
| 202: | if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
|
| 203: | $found_stub = $stub;
|
| 204: | } else {
|
| 205: |
|
| 206: | $_SESSION['XOOPS_G_STUBS'][] = $stub;
|
| 207: | }
|
| 208: | } else {
|
| 209: | if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
|
| 210: |
|
| 211: | $timeout_flag = true;
|
| 212: | }
|
| 213: | }
|
| 214: | }
|
| 215: |
|
| 216: |
|
| 217: | if (empty($found_stub)) {
|
| 218: | if (empty($timeout_flag)) {
|
| 219: | $this->_errors[] = $this->messages['err_nopair'];
|
| 220: | } else {
|
| 221: | $this->_errors[] = $this->messages['err_timeout'];
|
| 222: | }
|
| 223: | } else {
|
| 224: |
|
| 225: |
|
| 226: |
|
| 227: | if (!$area && isset($xoopsModule) && is_object($xoopsModule)) {
|
| 228: | $area = $xoopsModule->getVar('dirname');
|
| 229: | }
|
| 230: |
|
| 231: |
|
| 232: | if (isset($found_stub['area']) && $found_stub['area'] == $area) {
|
| 233: | $area_check = true;
|
| 234: | }
|
| 235: |
|
| 236: | if (!empty($found_stub['referer']) && isset($_SERVER['HTTP_REFERER']) && false !== strpos($_SERVER['HTTP_REFERER'], $found_stub['referer'])) {
|
| 237: | $referer_check = true;
|
| 238: | }
|
| 239: |
|
| 240: |
|
| 241: | if (empty($area_check) && empty($referer_check)) {
|
| 242: | $this->_errors[] = $this->messages['err_areaorref'];
|
| 243: | }
|
| 244: | }
|
| 245: |
|
| 246: | if (!empty($this->_errors)) {
|
| 247: | if ($allow_repost) {
|
| 248: |
|
| 249: | $this->draw_repost_form($area);
|
| 250: | exit;
|
| 251: | } else {
|
| 252: |
|
| 253: | $this->clear();
|
| 254: |
|
| 255: | return false;
|
| 256: | }
|
| 257: | } else {
|
| 258: |
|
| 259: | return true;
|
| 260: | }
|
| 261: | }
|
| 262: |
|
| 263: |
|
| 264: | |
| 265: | |
| 266: |
|
| 267: | public function draw_repost_form($area = '')
|
| 268: | {
|
| 269: |
|
| 270: | if (headers_sent()) {
|
| 271: | restore_error_handler();
|
| 272: | set_error_handler(array(&$this, 'errorHandler4FindOutput'));
|
| 273: | header('Dummy: for warning');
|
| 274: | restore_error_handler();
|
| 275: | exit;
|
| 276: | }
|
| 277: |
|
| 278: | error_reporting(0);
|
| 279: | while (ob_get_level()) {
|
| 280: | ob_end_clean();
|
| 281: | }
|
| 282: |
|
| 283: | $table = '<table>';
|
| 284: | $form = '<form action="?' . htmlspecialchars(isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '', ENT_QUOTES) . '" method="post">';
|
| 285: |
|
| 286: | foreach ($_POST as $key => $val) {
|
| 287: | if ($key === 'XOOPS_G_TICKET') {
|
| 288: | continue;
|
| 289: | }
|
| 290: | if (@get_magic_quotes_gpc()) {
|
| 291: | $key = stripslashes($key);
|
| 292: | }
|
| 293: | if (is_array($val)) {
|
| 294: | list($tmp_table, $tmp_form) = $this->extract_post_recursive(htmlspecialchars($key, ENT_QUOTES), $val);
|
| 295: | $table .= $tmp_table;
|
| 296: | $form .= $tmp_form;
|
| 297: | } else {
|
| 298: | if (@get_magic_quotes_gpc()) {
|
| 299: | $val = stripslashes($val);
|
| 300: | }
|
| 301: | $table .= '<tr><th>' . htmlspecialchars($key, ENT_QUOTES) . '</th><td>' . htmlspecialchars($val, ENT_QUOTES) . '</td></tr>' . "\n";
|
| 302: | $form .= '<input type="hidden" name="' . htmlspecialchars($key, ENT_QUOTES) . '" value="' . htmlspecialchars($val, ENT_QUOTES) . '" />' . "\n";
|
| 303: | }
|
| 304: | }
|
| 305: | $table .= '</table>';
|
| 306: | $form .= $this->getTicketHtml(__LINE__, 300, $area) . '<input type="submit" value="' . $this->messages['btn_repost'] . '" /></form>';
|
| 307: |
|
| 308: | echo '<html><head><title>' . $this->messages['err_general'] . '</title><style>table,td,th {border:solid black 1px; border-collapse:collapse;}</style></head><body>' . sprintf($this->messages['fmt_prompt4repost'], $this->getErrors()) . $table . $form . '</body></html>';
|
| 309: | }
|
| 310: |
|
| 311: | |
| 312: | |
| 313: | |
| 314: | |
| 315: | |
| 316: |
|
| 317: | public function extract_post_recursive($key_name, $tmp_array)
|
| 318: | {
|
| 319: | $table = '';
|
| 320: | $form = '';
|
| 321: | foreach ($tmp_array as $key => $val) {
|
| 322: | if (@get_magic_quotes_gpc()) {
|
| 323: | $key = stripslashes($key);
|
| 324: | }
|
| 325: | if (is_array($val)) {
|
| 326: | list($tmp_table, $tmp_form) = $this->extract_post_recursive($key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']', $val);
|
| 327: | $table .= $tmp_table;
|
| 328: | $form .= $tmp_form;
|
| 329: | } else {
|
| 330: | if (@get_magic_quotes_gpc()) {
|
| 331: | $val = stripslashes($val);
|
| 332: | }
|
| 333: | $table .= '<tr><th>' . $key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']</th><td>' . htmlspecialchars($val, ENT_QUOTES) . '</td></tr>' . "\n";
|
| 334: | $form .= '<input type="hidden" name="' . $key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']" value="' . htmlspecialchars($val, ENT_QUOTES) . '" />' . "\n";
|
| 335: | }
|
| 336: | }
|
| 337: |
|
| 338: | return array($table, $form);
|
| 339: | }
|
| 340: |
|
| 341: |
|
| 342: | public function clear()
|
| 343: | {
|
| 344: | $_SESSION['XOOPS_G_STUBS'] = array();
|
| 345: | }
|
| 346: |
|
| 347: |
|
| 348: | |
| 349: | |
| 350: |
|
| 351: | public function using()
|
| 352: | {
|
| 353: | if (!empty($_SESSION['XOOPS_G_STUBS'])) {
|
| 354: | return true;
|
| 355: | } else {
|
| 356: | return false;
|
| 357: | }
|
| 358: | }
|
| 359: |
|
| 360: |
|
| 361: | |
| 362: | |
| 363: | |
| 364: | |
| 365: |
|
| 366: | public function getErrors($ashtml = true)
|
| 367: | {
|
| 368: | if ($ashtml) {
|
| 369: | $ret = '';
|
| 370: | foreach ($this->_errors as $msg) {
|
| 371: | $ret .= "$msg<br>\n";
|
| 372: | }
|
| 373: | } else {
|
| 374: | $ret = $this->_errors;
|
| 375: | }
|
| 376: |
|
| 377: | return $ret;
|
| 378: | }
|
| 379: |
|
| 380: | |
| 381: | |
| 382: | |
| 383: | |
| 384: | |
| 385: | |
| 386: |
|
| 387: | public function errorHandler4FindOutput($errNo, $errStr, $errFile, $errLine)
|
| 388: | {
|
| 389: | if (preg_match('#' . preg_quote(XOOPS_ROOT_PATH, '#') . '([^:]+)\:(\d+)?#', $errStr, $regs)) {
|
| 390: | echo 'Irregular output! check the file ' . htmlspecialchars($regs[1], ENT_QUOTES) . ' line ' . htmlspecialchars($regs[2], ENT_QUOTES);
|
| 391: | } else {
|
| 392: | echo 'Irregular output! check language files etc.';
|
| 393: | }
|
| 394: |
|
| 395: | return null;
|
| 396: | }
|
| 397: |
|
| 398: | }
|
| 399: |
|
| 400: |
|
| 401: | $GLOBALS['xoopsGTicket'] = new XoopsGTicket();
|
| 402: | }
|
| 403: |
|
| 404: | if (!function_exists('admin_refcheck')) {
|
| 405: |
|
| 406: |
|
| 407: | |
| 408: | |
| 409: | |
| 410: | |
| 411: |
|
| 412: | function admin_refcheck($chkref = '')
|
| 413: | {
|
| 414: | if (empty($_SERVER['HTTP_REFERER'])) {
|
| 415: | return true;
|
| 416: | } else {
|
| 417: | $ref = $_SERVER['HTTP_REFERER'];
|
| 418: | }
|
| 419: | $cr = XOOPS_URL;
|
| 420: | if ($chkref != '') {
|
| 421: | $cr .= $chkref;
|
| 422: | }
|
| 423: | return !(strpos($ref, $cr) !== 0);
|
| 424: | }
|
| 425: | }
|
| 426: | |