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: