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: | |