source: temp/test-xoops.ec-cube.net/html/modules/tinyd0/include/gtickets.php @ 405

Revision 405, 9.2 KB checked in by root, 20 years ago (diff)
Line 
1<?php
2// GIJOE's Ticket Class (based on Marijuana's Oreteki XOOPS)
3// nobunobu's suggestions are applied
4
5if( ! class_exists( 'XoopsGTicket' ) ) {
6
7class XoopsGTicket {
8
9    var $_errors = array() ;
10    var $_latest_token = '' ;
11    var $messages = array() ;
12
13    function XoopsGTicket()
14    {
15        global $xoopsConfig ;
16
17        // language file
18        if( defined( 'XOOPS_ROOT_PATH' ) && ! empty( $xoopsConfig['language'] ) && ! strstr( $xoopsConfig['language'] , '/' ) ) {
19            if( file_exists( dirname( dirname( __FILE__ ) ) . '/language/' . $xoopsConfig['language'] . '/gticket_messages.phtml' ) ) {
20                include dirname( dirname( __FILE__ ) ) . '/language/' . $xoopsConfig['language'] . '/gticket_messages.phtml' ;
21            }
22        }
23
24        // default messages
25        if( empty( $this->messages ) ) $this->messages = array(
26            'err_general' => 'GTicket Error' ,
27            'err_nostubs' => 'No stubs found' ,
28            'err_noticket' => 'No ticket found' ,
29            'err_nopair' => 'No valid ticket-stub pair found' ,
30            'err_timeout' => 'Time out' ,
31            'err_areaorref' => 'Invalid area or referer' ,
32            '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?' ,
33            'btn_repost' => 'repost' ,
34        ) ;
35    }
36
37    // render form as plain html
38    function getTicketHtml( $salt = '' , $timeout = 1800 , $area = '' )
39    {
40        return '<input type="hidden" name="XOOPS_G_TICKET" value="'.$this->issue( $salt , $timeout , $area ).'" />' ;
41    }
42
43    // returns an object of XoopsFormHidden including theh ticket
44    function getTicketXoopsForm( $salt = '' , $timeout = 1800 , $area = '' )
45    {
46        return new XoopsFormHidden( 'XOOPS_G_TICKET' , $this->issue( $salt , $timeout , $area ) ) ;
47    }
48
49    // add a ticket as Hidden Element into XoopsForm
50    function addTicketXoopsFormElement( &$form , $salt = '' , $timeout = 1800 , $area = '' )
51    {
52        $form->addElement( new XoopsFormHidden( 'XOOPS_G_TICKET' , $this->issue( $salt , $timeout , $area ) ) ) ;
53    }
54
55    // returns an array for xoops_confirm() ;
56    function getTicketArray( $salt = '' , $timeout = 1800 , $area = '' )
57    {
58        return array( 'XOOPS_G_TICKET' => $this->issue( $salt , $timeout , $area ) ) ;
59    }
60
61    // return GET parameter string.
62    function getTicketParamString( $salt = '' , $noamp = false , $timeout=1800 , $area = '' )
63    {
64        return ( $noamp ? '' : '&amp;' ) . 'XOOPS_G_TICKET=' . $this->issue( $salt, $timeout , $area ) ;
65    }
66
67    // issue a ticket
68    function issue( $salt = '' , $timeout = 1800 , $area = '' )
69    {
70        global $xoopsModule ;
71   
72        // create a token
73        list( $usec , $sec ) = explode( " " , microtime() ) ;
74        $appendix_salt = empty( $_SERVER['PATH'] ) ? XOOPS_DB_NAME : $_SERVER['PATH'] ;
75        $token = crypt( $salt . $usec . $appendix_salt . $sec ) ;
76        $this->_latest_token = $token ;
77
78        if( empty( $_SESSION['XOOPS_G_STUBS'] ) ) $_SESSION['XOOPS_G_STUBS'] = array() ;
79
80        // limit max stubs 10
81        if( sizeof( $_SESSION['XOOPS_G_STUBS'] ) > 10 ) {
82            $_SESSION['XOOPS_G_STUBS'] = array_slice( $_SESSION['XOOPS_G_STUBS'] , -10 ) ;
83        }
84
85        // record referer if browser send it
86        $referer = empty( $_SERVER['HTTP_REFERER'] ) ? '' : $_SERVER['REQUEST_URI'] ;
87
88        // area as module's dirname
89        if( ! $area && is_object( @$xoopsModule ) ) {
90            $area = $xoopsModule->getVar('dirname') ;
91        }
92
93        // store stub
94        $_SESSION['XOOPS_G_STUBS'][] = array(
95            'expire' => time() + $timeout ,
96            'referer' => $referer ,
97            'area' => $area ,
98            'token' => $token
99        ) ;
100
101        // paid md5ed token as a ticket
102        return md5( $token . XOOPS_DB_PREFIX ) ;
103    }
104
105    // check a ticket
106    function check( $post = true , $area = '' , $allow_repost = true )
107    {
108        global $xoopsModule ;
109
110        $this->_errors = array() ;
111
112        // CHECK: stubs are not stored in session
113        if( ! is_array(@$_SESSION['XOOPS_G_STUBS'])) {
114            $this->_errors[] = $this->messages['err_nostubs'] ;
115            $_SESSION['XOOPS_G_STUBS'] = array() ;
116        }
117
118        // get key&val of the ticket from a user's query
119        $ticket = $post ? @$_POST['XOOPS_G_TICKET'] : @$_GET['XOOPS_G_TICKET'] ;
120
121        // CHECK: no tickets found
122        if( empty( $ticket ) ) {
123            $this->_errors[] = $this->messages['err_noticket'] ;
124        }
125
126        // gargage collection & find a right stub
127        $stubs_tmp = $_SESSION['XOOPS_G_STUBS'] ;
128        $_SESSION['XOOPS_G_STUBS'] = array() ;
129        foreach( $stubs_tmp as $stub ) {
130            // default lifetime 30min
131            if( $stub['expire'] >= time() ) {
132                if( md5( $stub['token'] . XOOPS_DB_PREFIX ) === $ticket ) {
133                    $found_stub = $stub ;
134                } else {
135                    // store the other valid stubs into session
136                    $_SESSION['XOOPS_G_STUBS'][] = $stub ;
137                }
138            } else {
139                if( md5( $stub['token'] . XOOPS_DB_PREFIX ) === $ticket ) {
140                    // not CSRF but Time-Out
141                    $timeout_flag = true ;
142                }
143            }
144        }
145
146        // CHECK: the right stub found or not
147        if( empty( $found_stub ) ) {
148            if( empty( $timeout_flag ) ) $this->_errors[] = $this->messages['err_nopair'] ;
149            else $this->_errors[] = $this->messages['err_timeout'] ;
150        } else {
151
152            // set area if necessary
153            // area as module's dirname
154            if( ! $area && is_object( @$xoopsModule ) ) {
155                $area = $xoopsModule->getVar('dirname') ;
156            }
157
158            // check area or referer
159            if( @$found_stub['area'] == $area ) $area_check = true ;
160            if( ! empty( $found_stub['referer'] ) && strstr( @$_SERVER['HTTP_REFERER'] , $found_stub['referer'] ) ) $referer_check = true ;
161
162            if( empty( $area_check ) && empty( $referer_check ) ) { // loose
163                $this->_errors[] = $this->messages['err_areaorref'] ;
164            }
165        }
166
167        if( ! empty( $this->_errors ) ) {
168            if( $allow_repost ) {
169                // repost form
170                $this->draw_repost_form( $area ) ;
171                exit ;
172            } else {
173                // failed
174                $this->clear() ;
175                return false ;
176            }
177        } else {
178            // all green
179            return true;
180        }
181    }
182
183    // draw form for repost
184    function draw_repost_form( $area = '' )
185    {
186        // Notify which file is broken
187        if( headers_sent() ) {
188            restore_error_handler() ;
189            set_error_handler( 'GTicket_ErrorHandler4FindOutput' ) ;
190            header( 'Dummy: for warning' ) ;
191            restore_error_handler() ;
192            exit ;
193        }
194   
195        error_reporting( 0 ) ;
196        while( ob_get_level() ) ob_end_clean() ;
197
198        $table = '<table>' ;
199        $form = '<form action="?'.htmlspecialchars(@$_SERVER['QUERY_STRING'],ENT_QUOTES).'" method="post" >' ;
200        foreach( $_POST as $key => $val ) {
201            if( $key == 'XOOPS_G_TICKET' ) continue ;
202            if( get_magic_quotes_gpc() ) {
203                $key = stripslashes( $key ) ;
204            }
205            if( is_array( $val ) ) {
206                list( $tmp_table , $tmp_form ) = $this->extract_post_recursive( htmlspecialchars($key,ENT_QUOTES) , $val ) ;
207                $table .= $tmp_table ;
208                $form .= $tmp_form ;
209            } else {
210                if( get_magic_quotes_gpc() ) {
211                    $val = stripslashes( $val ) ;
212                }
213                $table .= '<tr><th>'.htmlspecialchars($key,ENT_QUOTES).'</th><td>'.htmlspecialchars($val,ENT_QUOTES).'</td></tr>'."\n" ;
214                $form .= '<input type="hidden" name="'.htmlspecialchars($key,ENT_QUOTES).'" value="'.htmlspecialchars($val,ENT_QUOTES).'" />'."\n" ;
215            }
216        }
217        $table .= '</table>' ;
218        $form .= $this->getTicketHtml(__LINE__,300,$area).'<input type="submit" value="'.$this->messages['btn_repost'].'" /></form>' ;
219
220        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>' ;
221    }
222
223    function extract_post_recursive( $key_name , $tmp_array ) {
224        $table = '' ;
225        $form = '' ;
226        foreach( $tmp_array as $key => $val ) {
227            if( get_magic_quotes_gpc() ) {
228                $key = stripslashes( $key ) ;
229            }
230            if( is_array( $val ) ) {
231                list( $tmp_table , $tmp_form ) = $this->extract_post_recursive( $key_name.'['.htmlspecialchars($key,ENT_QUOTES).']' , $val ) ;
232                $table .= $tmp_table ;
233                $form .= $tmp_form ;
234            } else {
235                if( get_magic_quotes_gpc() ) {
236                    $val = stripslashes( $val ) ;
237                }
238                $table .= '<tr><th>'.$key_name.'['.htmlspecialchars($key,ENT_QUOTES).']</th><td>'.htmlspecialchars($val,ENT_QUOTES).'</td></tr>'."\n" ;
239                $form .= '<input type="hidden" name="'.$key_name.'['.htmlspecialchars($key,ENT_QUOTES).']" value="'.htmlspecialchars($val,ENT_QUOTES).'" />'."\n" ;
240            }
241        }
242        return array( $table , $form ) ;
243    }
244
245
246    // clear all stubs
247    function clear()
248    {
249        $_SESSION['XOOPS_G_STUBS'] = array() ;
250    }
251
252
253    // Ticket Using
254    function using()
255    {
256        if( ! empty( $_SESSION['XOOPS_G_STUBS'] ) ) {
257            return true;
258        } else {
259            return false;
260        }
261    }
262
263
264    // return errors
265    function getErrors( $ashtml = true )
266    {
267        if( $ashtml ) {
268            $ret = '' ;
269            foreach( $this->_errors as $msg ) {
270                $ret .= "$msg<br />\n" ;
271            }
272        } else {
273            $ret = $this->_errors ;
274        }
275        return $ret ;
276    }
277
278// end of class
279}
280
281function GTicket_ErrorHandler4FindOutput($errNo, $errStr, $errFile, $errLine)
282{
283    if( preg_match( '?'.preg_quote(XOOPS_ROOT_PATH).'([^:]+)\:(\d+)?' , $errStr , $regs ) ) {
284        echo "Irregular output! check the file ".htmlspecialchars($regs[1])." line ".htmlspecialchars($regs[2]) ;
285    } else {
286        echo "Irregular output! check language files etc." ;
287    }
288    return ;
289}
290
291// create a instance in global scope
292$GLOBALS['xoopsGTicket'] = new XoopsGTicket() ;
293
294}
295
296if( ! function_exists( 'admin_refcheck' ) ) {
297
298//Admin Referer Check By Marijuana(Rev.011)
299function admin_refcheck($chkref = "") {
300    if( empty( $_SERVER['HTTP_REFERER'] ) ) {
301        return true ;
302    } else {
303        $ref = $_SERVER['HTTP_REFERER'];
304    }
305    $cr = XOOPS_URL;
306    if ( $chkref != "" ) { $cr .= $chkref; }
307    if ( strpos($ref, $cr) !== 0 ) { return false; }
308    return true;
309}
310
311}
312
313
314?>
Note: See TracBrowser for help on using the repository browser.