1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11:
12: 13: 14: 15: 16: 17: 18: 19: 20:
21:
22:
23:
24:
25: if (!class_exists('XoopsGTicket')) {
26:
27: class XoopsGTicket
28: {
29:
30: var $_errors = array();
31: var $_latest_token = '';
32: var $messages = array();
33:
34: function XoopsGTicket()
35: {
36: $xoops = Xoops::getInstance();
37: $language = $xoops->getConfig('language');
38:
39:
40: if ($language && !strstr($language, '/')) {
41: if (XoopsLoad::fileExists(dirname(__DIR__) . '/language/' . $language . '/gticket_messages.phtml')) {
42: include dirname(__DIR__) . '/language/' . $language . '/gticket_messages.phtml';
43: }
44: }
45:
46:
47: if (empty($this->messages)) {
48: $this->messages = array(
49: 'err_general' => 'GTicket Error', 'err_nostubs' => 'No stubs found',
50: 'err_noticket' => 'No ticket found', 'err_nopair' => 'No valid ticket-stub pair found',
51: 'err_timeout' => 'Time out', 'err_areaorref' => 'Invalid area or referer',
52: '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?',
53: 'btn_repost' => 'repost',
54: );
55: }
56: }
57:
58:
59: function getTicketHtml($salt = '', $timeout = 1800, $area = '')
60: {
61: return '<input type="hidden" name="XOOPS_G_TICKET" value="' . $this->issue($salt, $timeout, $area) . '" />';
62: }
63:
64:
65: function getTicketXoopsForm($salt = '', $timeout = 1800, $area = '')
66: {
67: return new Xoops\Form\Hidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area));
68: }
69:
70:
71: function addTicketXoopsFormElement(&$form, $salt = '', $timeout = 1800, $area = '')
72: {
73: $form->addElement(new Xoops\Form\Hidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area)));
74: }
75:
76:
77: function getTicketArray($salt = '', $timeout = 1800, $area = '')
78: {
79: return array('XOOPS_G_TICKET' => $this->issue($salt, $timeout, $area));
80: }
81:
82:
83: function getTicketParamString($salt = '', $noamp = false, $timeout = 1800, $area = '')
84: {
85: return ($noamp ? '' : '&') . 'XOOPS_G_TICKET=' . $this->issue($salt, $timeout, $area);
86: }
87:
88:
89: function issue($salt = '', $timeout = 1800, $area = '')
90: {
91: $xoops = Xoops::getInstance();
92:
93:
94: list($usec, $sec) = explode(" ", microtime());
95: $appendix_salt = empty($_SERVER['PATH']) ? \XoopsBaseConfig::get('db-name') : $_SERVER['PATH'];
96: $token = crypt($salt . $usec . $appendix_salt . $sec);
97: $this->_latest_token = $token;
98:
99: if (empty($_SESSION['XOOPS_G_STUBS'])) {
100: $_SESSION['XOOPS_G_STUBS'] = array();
101: }
102:
103:
104: if (sizeof($_SESSION['XOOPS_G_STUBS']) > 10) {
105: $_SESSION['XOOPS_G_STUBS'] = array_slice($_SESSION['XOOPS_G_STUBS'], -10);
106: }
107:
108:
109: $referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['REQUEST_URI'];
110:
111:
112: if (!$area && $xoops->isModule()) {
113: $area = $xoops->module->getVar('dirname');
114: }
115:
116:
117: $_SESSION['XOOPS_G_STUBS'][] = array(
118: 'expire' => time() + $timeout, 'referer' => $referer, 'area' => $area, 'token' => $token
119: );
120:
121:
122: return md5($token . \XoopsBaseConfig::get('db-prefix'));
123: }
124:
125:
126: function check($post = true, $area = '', $allow_repost = true)
127: {
128: $xoops = Xoops::getInstance();
129: $this->_errors = array();
130:
131:
132: if (!is_array(@$_SESSION['XOOPS_G_STUBS'])) {
133: $this->_errors[] = $this->messages['err_nostubs'];
134: $_SESSION['XOOPS_G_STUBS'] = array();
135: }
136:
137:
138: $ticket = $post ? @$_POST['XOOPS_G_TICKET'] : @$_GET['XOOPS_G_TICKET'];
139:
140:
141: if (empty($ticket)) {
142: $this->_errors[] = $this->messages['err_noticket'];
143: }
144:
145:
146: $stubs_tmp = $_SESSION['XOOPS_G_STUBS'];
147: $_SESSION['XOOPS_G_STUBS'] = array();
148: foreach ($stubs_tmp as $stub) {
149:
150: if ($stub['expire'] >= time()) {
151: if (md5($stub['token'] . \XoopsBaseConfig::get('db-prefix')) === $ticket) {
152: $found_stub = $stub;
153: } else {
154:
155: $_SESSION['XOOPS_G_STUBS'][] = $stub;
156: }
157: } else {
158: if (md5($stub['token'] . \XoopsBaseConfig::get('db-prefix')) === $ticket) {
159:
160: $timeout_flag = true;
161: }
162: }
163: }
164:
165:
166: if (empty($found_stub)) {
167: if (empty($timeout_flag)) {
168: $this->_errors[] = $this->messages['err_nopair'];
169: } else {
170: $this->_errors[] = $this->messages['err_timeout'];
171: }
172: } else {
173:
174:
175:
176: if (!$area && $xoops->isModule()) {
177: $area = $xoops->module->getVar('dirname');
178: }
179:
180:
181: if (@$found_stub['area'] == $area) {
182: $area_check = true;
183: }
184: if (!empty($found_stub['referer']) && strstr(@$_SERVER['HTTP_REFERER'], $found_stub['referer'])) {
185: $referer_check = true;
186: }
187:
188: if (empty($area_check) && empty($referer_check)) {
189: $this->_errors[] = $this->messages['err_areaorref'];
190: }
191: }
192:
193: if (!empty($this->_errors)) {
194: if ($allow_repost) {
195:
196: $this->draw_repost_form($area);
197: exit;
198: } else {
199:
200: $this->clear();
201: return false;
202: }
203: } else {
204:
205: return true;
206: }
207: }
208:
209:
210: function draw_repost_form($area = '')
211: {
212:
213: if (headers_sent()) {
214: restore_error_handler();
215: set_error_handler(array(&$this, 'errorHandler4FindOutput'));
216: header('Dummy: for warning');
217: restore_error_handler();
218: exit;
219: }
220:
221: error_reporting(0);
222: while (ob_get_level()) {
223: ob_end_clean();
224: }
225:
226: $table = '<table>';
227: $form = '<form action="?' . htmlspecialchars(@$_SERVER['QUERY_STRING'], ENT_QUOTES) . '" method="post" >';
228: foreach ($_POST as $key => $val) {
229: if ($key === 'XOOPS_G_TICKET') {
230: continue;
231: }
232: if (get_magic_quotes_gpc()) {
233: $key = stripslashes($key);
234: }
235: if (is_array($val)) {
236: list($tmp_table, $tmp_form) = $this->extract_post_recursive(htmlspecialchars($key, ENT_QUOTES), $val);
237: $table .= $tmp_table;
238: $form .= $tmp_form;
239: } else {
240: if (get_magic_quotes_gpc()) {
241: $val = stripslashes($val);
242: }
243: $table .= '<tr><th>' . htmlspecialchars($key, ENT_QUOTES) . '</th><td>' . htmlspecialchars($val, ENT_QUOTES) . '</td></tr>' . "\n";
244: $form .= '<input type="hidden" name="' . htmlspecialchars($key, ENT_QUOTES) . '" value="' . htmlspecialchars($val, ENT_QUOTES) . '" />' . "\n";
245: }
246: }
247: $table .= '</table>';
248: $form .= $this->getTicketHtml(__LINE__, 300, $area) . '<input type="submit" value="' . $this->messages['btn_repost'] . '" /></form>';
249:
250: 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>';
251: }
252:
253: 254: 255:
256: function extract_post_recursive($key_name, $tmp_array)
257: {
258: $table = '';
259: $form = '';
260: foreach ($tmp_array as $key => $val) {
261: if (get_magic_quotes_gpc()) {
262: $key = stripslashes($key);
263: }
264: if (is_array($val)) {
265: list($tmp_table, $tmp_form) = $this->extract_post_recursive($key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']', $val);
266: $table .= $tmp_table;
267: $form .= $tmp_form;
268: } else {
269: if (get_magic_quotes_gpc()) {
270: $val = stripslashes($val);
271: }
272: $table .= '<tr><th>' . $key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']</th><td>' . htmlspecialchars($val, ENT_QUOTES) . '</td></tr>' . "\n";
273: $form .= '<input type="hidden" name="' . $key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']" value="' . htmlspecialchars($val, ENT_QUOTES) . '" />' . "\n";
274: }
275: }
276: return array($table, $form);
277: }
278:
279:
280:
281: function clear()
282: {
283: $_SESSION['XOOPS_G_STUBS'] = array();
284: }
285:
286:
287:
288: function using()
289: {
290: if (!empty($_SESSION['XOOPS_G_STUBS'])) {
291: return true;
292: } else {
293: return false;
294: }
295: }
296:
297:
298:
299: function getErrors($ashtml = true)
300: {
301: if ($ashtml) {
302: $ret = '';
303: foreach ($this->_errors as $msg) {
304: $ret .= "$msg<br />\n";
305: }
306: } else {
307: $ret = $this->_errors;
308: }
309: return $ret;
310: }
311:
312: function errorHandler4FindOutput($errNo, $errStr, $errFile, $errLine)
313: {
314: if (preg_match('?' . preg_quote(\XoopsBaseConfig::get('root-path')) . '([^:]+)\:(\d+)?', $errStr, $regs)) {
315: echo "Irregular output! check the file " . htmlspecialchars($regs[1]) . " line " . htmlspecialchars($regs[2]);
316: } else {
317: echo "Irregular output! check language files etc.";
318: }
319: return;
320: }
321:
322: }
323:
324:
325: $GLOBALS['xoopsGTicket'] = new XoopsGTicket();
326:
327: }
328:
329: if (!function_exists('admin_refcheck')) {
330:
331:
332: function admin_refcheck($chkref = "")
333: {
334: if (empty($_SERVER['HTTP_REFERER'])) {
335: return true;
336: } else {
337: $ref = $_SERVER['HTTP_REFERER'];
338: }
339: $cr = \XoopsBaseConfig::get('url');
340: if ($chkref != "") {
341: $cr .= $chkref;
342: }
343: if (strpos($ref, $cr) !== 0) {
344: return false;
345: }
346: return true;
347: }
348:
349: }
350: