XoopsGTicket::clear()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 * You may not change or alter any portion of this comment or credits
4
 * of supporting developers from this source code or any supporting source code
5
 * which is considered copyrighted (c) material of the original comment or credit authors.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
/**
13
 * @copyright   {@link http://xoops.org/ XOOPS Project}
14
 * @license     {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
15
 * @package
16
 * @since
17
 * @author       XOOPS Development Team,
18
 * @author       GIJ=CHECKMATE (PEAK Corp. http://www.peak.ne.jp/)
19
 * @author       Antiques Promotion (http://www.antiquespromotion.ca)
20
 *              (based on Marijuana's Oreteki XOOPS)
21
 *              nobunobu's suggestions are applied
22
 */
23
24
if (!class_exists('XoopsGTicket')) {
25
    /**
26
     * Class XoopsGTicket
27
     */
28
    class XoopsGTicket
29
    {
30
        public $_errors       = array();
31
        public $_latest_token = '';
32
33
        // render form as plain html
34
35
        /**
36
         * @param  string $salt
37
         * @param  int    $timeout
38
         * @param  string $area
39
         * @return string
40
         */
41
        public function getTicketHtml($salt = '', $timeout = 1800, $area = '')
42
        {
43
            return '<input type="hidden" name="XOOPS_G_TICKET" value="' . $this->issue($salt, $timeout, $area) . '" />';
44
        }
45
46
        // returns an object of XoopsFormHidden including theh ticket
47
48
        /**
49
         * @param  string $salt
50
         * @param  int    $timeout
51
         * @param  string $area
52
         * @return XoopsFormHidden
53
         */
54
        public function getTicketXoopsForm($salt = '', $timeout = 1800, $area = '')
55
        {
56
            return new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area));
57
        }
58
59
        // add a ticket as Hidden Element into XoopsForm
60
61
        /**
62
         * @param        $form
63
         * @param string $salt
64
         * @param int    $timeout
65
         * @param string $area
66
         */
67
        public function addTicketXoopsFormElement(&$form, $salt = '', $timeout = 1800, $area = '')
68
        {
69
            $form->addElement(new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area)));
70
        }
71
72
        // returns an array for xoops_confirm() ;
73
74
        /**
75
         * @param  string $salt
76
         * @param  int    $timeout
77
         * @param  string $area
78
         * @return array
79
         */
80
        public function getTicketArray($salt = '', $timeout = 1800, $area = '')
81
        {
82
            return array('XOOPS_G_TICKET' => $this->issue($salt, $timeout, $area));
83
        }
84
85
        // return GET parameter string.
86
87
        /**
88
         * @param  string $salt
89
         * @param  bool   $noamp
90
         * @param  int    $timeout
91
         * @param  string $area
92
         * @return string
93
         */
94
        public function getTicketParamString($salt = '', $noamp = false, $timeout = 1800, $area = '')
95
        {
96
            return ($noamp ? '' : '&amp;') . 'XOOPS_G_TICKET=' . $this->issue($salt, $timeout, $area);
97
        }
98
99
        // issue a ticket
100
101
        /**
102
         * @param  string $salt
103
         * @param  int    $timeout
104
         * @param  string $area
105
         * @return string
106
         */
107
        public function issue($salt = '', $timeout = 1800, $area = '')
108
        {
109
            global $xoopsModule;
110
            if ('' === $salt) {
111
                if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
112
                    // $salt = '$2y$07$' . strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
113
                    $salt = '$2y$07$' . str_replace('+', '.', base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)));
114
                }
115
            }
116
            // create a token
117
            list($usec, $sec) = explode(' ', microtime());
118
            $appendix_salt       = empty($_SERVER['PATH']) ? XOOPS_DB_NAME : $_SERVER['PATH'];
119
            $token               = crypt($salt . $usec . $appendix_salt . $sec, $salt);
120
            $this->_latest_token = $token;
121
122
            if (empty($_SESSION['XOOPS_G_STUBS'])) {
123
                $_SESSION['XOOPS_G_STUBS'] = array();
124
            }
125
126
            // limit max stubs 10
127
            if (count($_SESSION['XOOPS_G_STUBS']) > 10) {
128
                $_SESSION['XOOPS_G_STUBS'] = array_slice($_SESSION['XOOPS_G_STUBS'], -10);
129
            }
130
131
            // record referer if browser send it
132
            $referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['REQUEST_URI'];
133
134
            // area as module's dirname
135
            if (!$area && is_object(@$xoopsModule)) {
136
                $area = $xoopsModule->getVar('dirname');
137
            }
138
139
            // store stub
140
            $_SESSION['XOOPS_G_STUBS'][] = array(
141
                'expire'  => time() + $timeout,
142
                'referer' => $referer,
143
                'area'    => $area,
144
                'token'   => $token
145
            );
146
147
            // paid md5ed token as a ticket
148
            return md5($token . XOOPS_DB_PREFIX);
149
        }
150
151
        // check a ticket
152
153
        /**
154
         * @param  bool   $post
155
         * @param  string $area
156
         * @return bool
157
         */
158
        public function check($post = true, $area = '')
159
        {
160
            global $xoopsModule;
161
162
            $this->_errors = array();
163
164
            // CHECK: stubs are not stored in session
165
            if (empty($_SESSION['XOOPS_G_STUBS']) || !is_array($_SESSION['XOOPS_G_STUBS'])) {
166
                $this->clear();
167
                $this->_errors[] = 'Invalid Session';
168
169
                return false;
170
            }
171
172
            // get key&val of the ticket from a user's query
173
            if ($post) {
174
                $ticket = empty($_POST['XOOPS_G_TICKET']) ? '' : $_POST['XOOPS_G_TICKET'];
175
            } else {
176
                $ticket = empty($_GET['XOOPS_G_TICKET']) ? '' : $_GET['XOOPS_G_TICKET'];
177
            }
178
179
            // CHECK: no tickets found
180
            if (empty($ticket)) {
181
                $this->clear();
182
                $this->_errors[] = 'Irregular post found';
183
184
                return false;
185
            }
186
187
            // gargage collection & find a right stub
188
            $stubs_tmp                 = $_SESSION['XOOPS_G_STUBS'];
189
            $_SESSION['XOOPS_G_STUBS'] = array();
190
            foreach ($stubs_tmp as $stub) {
191
                // default lifetime 30min
192
                if ($stub['expire'] >= time()) {
193
                    if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
194
                        $found_stub = $stub;
195
                    } else {
196
                        // store the other valid stubs into session
197
                        $_SESSION['XOOPS_G_STUBS'][] = $stub;
198
                    }
199
                } else {
200
                    if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
201
                        // not CSRF but Time-Out
202
                        $timeout_flag = true;
203
                    }
204
                }
205
            }
206
207
            // CHECK: the right stub found or not
208
            if (empty($found_stub)) {
209
                $this->clear();
210
                if (empty($timeout_flag)) {
211
                    $this->_errors[] = 'Invalid Session';
212
                } else {
213
                    $this->_errors[] = 'Time out';
214
                }
215
216
                return false;
217
            }
218
219
            // set area if necessary
220
            // area as module's dirname
221
            if (!$area && is_object(@$xoopsModule)) {
222
                $area = $xoopsModule->getVar('dirname');
223
            }
224
225
            // check area or referer
226
            if (@$found_stub['area'] == $area) {
227
                $area_check = true;
228
            }
229
            if (!empty($found_stub['referer']) && true === strpos(@$_SERVER['HTTP_REFERER'], $found_stub['referer'])) {
230
                $referer_check = true;
231
            }
232
233
            // if ( empty( $area_check ) || empty( $referer_check ) ) { // restrict
234
            if (empty($area_check) && empty($referer_check)) { // loose
235
                $this->clear();
236
                $this->_errors[] = 'Invalid area or referer';
237
238
                return false;
239
            }
240
241
            // all green
242
            return true;
243
        }
244
245
        // clear all stubs
246
        public function clear()
247
        {
248
            $_SESSION['XOOPS_G_STUBS'] = array();
249
        }
250
251
        // Ticket Using
252
253
        /**
254
         * @return bool
255
         */
256
        public function using()
257
        {
258
            if (!empty($_SESSION['XOOPS_G_STUBS'])) {
259
                return true;
260
            } else {
261
                return false;
262
            }
263
        }
264
265
        // return errors
266
267
        /**
268
         * @param  bool $ashtml
269
         * @return array|string
270
         */
271
        public function getErrors($ashtml = true)
272
        {
273
            if ($ashtml) {
274
                $ret = '';
275
                foreach ($this->_errors as $msg) {
276
                    $ret .= "$msg<br>\n";
277
                }
278
            } else {
279
                $ret = $this->_errors;
280
            }
281
282
            return $ret;
283
        }
284
285
        // end of class
286
    }
287
288
    // create a instance in global scope
289
    $GLOBALS['xoopsGTicket'] = new XoopsGTicket();
290
}
291
292
if (!function_exists('admin_refcheck')) {
293
294
    //Admin Referer Check By Marijuana(Rev.011)
295
    /**
296
     * @param  string $chkref
297
     * @return bool
298
     */
299
    function admin_refcheck($chkref = '')
300
    {
301
        if (empty($_SERVER['HTTP_REFERER'])) {
302
            return true;
303
        } else {
304
            $ref = $_SERVER['HTTP_REFERER'];
305
        }
306
        $cr = XOOPS_URL;
307
        if ($chkref !== '') {
308
            $cr .= $chkref;
309
        }
310
        if (strpos($ref, $cr) !== 0) {
311
            return false;
312
        }
313
314
        return true;
315
    }
316
}
317