Commit 201065da9ae669b90465dbc9e8fd8d7da6ea683a

Authored by kevin_fourie
1 parent 362a287d

Merged in from STABLE trunk...

KOA-120
"Session management security"
Updated.

Committed By: Conrad Vermeulen
Reviewed By: Martin Kirsten


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/STABLE/branches/3.5.3a-Release-Branch@9261 c91229c3-7414-0410-bfa2-8a42b809f60b
ktapi/KTAPISession.inc.php
... ... @@ -7,31 +7,31 @@
7 7 * Document Management Made Simple
8 8 * Copyright (C) 2008 KnowledgeTree Inc.
9 9 * Portions copyright The Jam Warehouse Software (Pty) Limited
10   - *
  10 + *
11 11 * This program is free software; you can redistribute it and/or modify it under
12 12 * the terms of the GNU General Public License version 3 as published by the
13 13 * Free Software Foundation.
14   - *
  14 + *
15 15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 18 * details.
19   - *
  19 + *
20 20 * You should have received a copy of the GNU General Public License
21 21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22   - *
23   - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  22 + *
  23 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
24 24 * California 94120-7775, or email info@knowledgetree.com.
25   - *
  25 + *
26 26 * The interactive user interfaces in modified source and object code versions
27 27 * of this program must display Appropriate Legal Notices, as required under
28 28 * Section 5 of the GNU General Public License version 3.
29   - *
  29 + *
30 30 * In accordance with Section 7(b) of the GNU General Public License version 3,
31 31 * these Appropriate Legal Notices must retain the display of the "Powered by
32   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  32 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
33 33 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
34   - * must display the words "Powered by KnowledgeTree" and retain the original
  34 + * must display the words "Powered by KnowledgeTree" and retain the original
35 35 * copyright notice.
36 36 * Contributor( s): ______________________________________
37 37 *
... ... @@ -124,10 +124,6 @@ class KTAPI_UserSession extends KTAPI_Session
124 124 $this->active = true;
125 125 }
126 126  
127   -
128   -
129   -
130   -
131 127 /**
132 128 * This resolves the user's ip
133 129 *
... ... @@ -164,18 +160,18 @@ class KTAPI_UserSession extends KTAPI_Session
164 160 * @static
165 161 * @param User $user
166 162 */
167   - function _check_session(&$user)
  163 + function _check_session(&$user, $ip, $app)
168 164 {
169 165 $user_id = $user->getId();
170 166  
171   - Session::removeStaleSessions();
  167 + Session::removeStaleSessions($user_id);
172 168  
173 169 $config = &KTConfig::getSingleton();
174 170 $validateSession = $config->get('webservice/validateSessionCount', false);
175 171  
176 172 if ($validateSession)
177 173 {
178   - $sql = "SELECT count(*) >= u.max_sessions as over_limit FROM active_sessions ass INNER JOIN users u ON ass.user_id=u.id WHERE ass.user_id = $user_id";
  174 + $sql = "SELECT count(*) >= u.max_sessions as over_limit FROM active_sessions ass INNER JOIN users u ON ass.user_id=u.id WHERE ass.user_id = $user_id AND ass.apptype != 'ws'";
179 175 $row = DBUtil::getOneResult($sql);
180 176  
181 177 if (PEAR::isError($row))
... ... @@ -193,18 +189,44 @@ class KTAPI_UserSession extends KTAPI_Session
193 189 }
194 190  
195 191 $session = session_id();
  192 + $newSessionRequired = false;
  193 + if ($app == 'ws')
  194 + {
  195 + $sql = "select id from active_sessions where user_id=$user_id AND apptype='ws' and ip='$ip'";
  196 +
  197 + $row = DBUtil::getOneResult($sql);
  198 + if (empty($row))
  199 + {
  200 + $newSessionRequired = true;
  201 + }
  202 + else
  203 + {
  204 + $sessionid = $row['id'];
  205 + $sql = "update active_sessions set session_id='$session' where id=$sessionid";
  206 +
  207 + DBUtil::runQuery($sql);
  208 + }
  209 + }
  210 + else
  211 + {
  212 + $newSessionRequired = true;
  213 + }
196 214  
197   - $sessionid = DBUtil::autoInsert('active_sessions',
198   - array(
199   - 'user_id' => $user_id,
200   - 'session_id' => session_id(),
201   - 'lastused' => date('Y-m-d H:i:s'),
202   - 'ip' => $ip
203   - ));
204   - if (PEAR::isError($sessionid) )
205   - {
206   - return $sessionid;
207   - }
  215 + if ($newSessionRequired)
  216 + {
  217 + $sessionid = DBUtil::autoInsert('active_sessions',
  218 + array(
  219 + 'user_id' => $user_id,
  220 + 'session_id' => session_id(),
  221 + 'lastused' => date('Y-m-d H:i:s'),
  222 + 'ip' => $ip,
  223 + 'apptype'=>$app
  224 + ));
  225 + if (PEAR::isError($sessionid) )
  226 + {
  227 + return $sessionid;
  228 + }
  229 + }
208 230  
209 231 return array($session,$sessionid);
210 232 }
... ... @@ -219,7 +241,7 @@ class KTAPI_UserSession extends KTAPI_Session
219 241 * @param string $password
220 242 * @return KTAPI_Session
221 243 */
222   - function &start_session(&$ktapi, $username, $password, $ip=null)
  244 + function &start_session(&$ktapi, $username, $password, $ip=null, $app='ws')
223 245 {
224 246 $this->active=false;
225 247 if ( empty($username) )
... ... @@ -247,11 +269,11 @@ class KTAPI_UserSession extends KTAPI_Session
247 269  
248 270 if (is_null($ip))
249 271 {
250   - $ip = '127.0.0.1';
251   - //$ip = KTAPI_Session::resolveIP();
  272 + //$ip = '127.0.0.1';
  273 + $ip = KTAPI_Session::resolveIP();
252 274 }
253 275  
254   - $result = KTAPI_UserSession::_check_session($user);
  276 + $result = KTAPI_UserSession::_check_session($user, $ip, $app);
255 277  
256 278 if (PEAR::isError($result))
257 279 {
... ... @@ -273,9 +295,9 @@ class KTAPI_UserSession extends KTAPI_Session
273 295 * @param string $ip
274 296 * @return KTAPI_Session
275 297 */
276   - function &get_active_session(&$ktapi, $session, $ip)
  298 + function &get_active_session(&$ktapi, $session, $ip, $app='ws')
277 299 {
278   - $sql = "SELECT id, user_id FROM active_sessions WHERE session_id='$session'";
  300 + $sql = "SELECT id, user_id FROM active_sessions WHERE session_id='$session' and apptype='$app'";
279 301 if (!empty($ip))
280 302 {
281 303 $sql .= " AND ip='$ip'";
... ... @@ -296,13 +318,10 @@ class KTAPI_UserSession extends KTAPI_Session
296 318 return new KTAPI_Error(KTAPI_ERROR_USER_INVALID, $user);
297 319 }
298 320  
299   -
300   -
301 321 $now=date('Y-m-d H:i:s');
302 322 $sql = "UPDATE active_sessions SET lastused='$now' WHERE id=$sessionid";
303 323 DBUtil::runQuery($sql);
304 324  
305   -
306 325 if ($user->isAnonymous())
307 326 $session = &new KTAPI_AnonymousSession($ktapi, $user, $session, $sessionid, $ip);
308 327 else
... ... @@ -333,7 +352,7 @@ class KTAPI_UserSession extends KTAPI_Session
333 352  
334 353 class KTAPI_AnonymousSession extends KTAPI_UserSession
335 354 {
336   - function &start_session(&$ktapi, $ip=null)
  355 + function &start_session(&$ktapi, $ip=null, $app = 'ws')
337 356 {
338 357 $user =& User::get(-2);
339 358 if (is_null($user) || PEAR::isError($user) || ($user === false) || !$user->isAnonymous())
... ... @@ -357,7 +376,7 @@ class KTAPI_AnonymousSession extends KTAPI_UserSession
357 376 //$ip = KTAPI_Session::resolveIP();
358 377 }
359 378  
360   - list($session,$sessionid) = KTAPI_UserSession::_check_session($user);
  379 + list($session,$sessionid) = KTAPI_UserSession::_check_session($user, $ip, $app);
361 380 if (PEAR::isError($sessionid))
362 381 {
363 382 return $sessionid;
... ...
ktapi/ktapi.inc.php
... ... @@ -8,31 +8,31 @@
8 8 * Document Management Made Simple
9 9 * Copyright (C) 2008 KnowledgeTree Inc.
10 10 * Portions copyright The Jam Warehouse Software (Pty) Limited
11   - *
  11 + *
12 12 * This program is free software; you can redistribute it and/or modify it under
13 13 * the terms of the GNU General Public License version 3 as published by the
14 14 * Free Software Foundation.
15   - *
  15 + *
16 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 19 * details.
20   - *
  20 + *
21 21 * You should have received a copy of the GNU General Public License
22 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23   - *
24   - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  23 + *
  24 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
25 25 * California 94120-7775, or email info@knowledgetree.com.
26   - *
  26 + *
27 27 * The interactive user interfaces in modified source and object code versions
28 28 * of this program must display Appropriate Legal Notices, as required under
29 29 * Section 5 of the GNU General Public License version 3.
30   - *
  30 + *
31 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 32 * these Appropriate Legal Notices must retain the display of the "Powered by
33   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  33 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
34 34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
35   - * must display the words "Powered by KnowledgeTree" and retain the original
  35 + * must display the words "Powered by KnowledgeTree" and retain the original
36 36 * copyright notice.
37 37 * Contributor( s): ______________________________________
38 38 *
... ... @@ -219,14 +219,14 @@ class KTAPI
219 219 * @param string $session
220 220 * @return KTAPI_Session
221 221 */
222   - function & get_active_session($session, $ip=null)
  222 + function & get_active_session($session, $ip=null, $app='ws')
223 223 {
224 224 if (!is_null($this->session))
225 225 {
226 226 return new PEAR_Error('A session is currently active.');
227 227 }
228 228  
229   - $session = &KTAPI_UserSession::get_active_session($this, $session, $ip);
  229 + $session = &KTAPI_UserSession::get_active_session($this, $session, $ip, $app);
230 230  
231 231 if (is_null($session) || PEAR::isError($session))
232 232 {
... ... @@ -245,14 +245,14 @@ class KTAPI
245 245 * @param string $password
246 246 * @return KTAPI_Session
247 247 */
248   - function & start_session($username, $password, $ip=null)
  248 + function & start_session($username, $password, $ip=null, $app='ws')
249 249 {
250 250 if (!is_null($this->session))
251 251 {
252 252 return new PEAR_Error('A session is currently active.');
253 253 }
254 254  
255   - $session = &KTAPI_UserSession::start_session($this, $username, $password, $ip);
  255 + $session = &KTAPI_UserSession::start_session($this, $username, $password, $ip, $app);
256 256 if (is_null($session))
257 257 {
258 258 return new PEAR_Error('Session is null.');
... ...
lib/session/Session.inc
... ... @@ -8,31 +8,31 @@
8 8 * Document Management Made Simple
9 9 * Copyright (C) 2008 KnowledgeTree Inc.
10 10 * Portions copyright The Jam Warehouse Software (Pty) Limited
11   - *
  11 + *
12 12 * This program is free software; you can redistribute it and/or modify it under
13 13 * the terms of the GNU General Public License version 3 as published by the
14 14 * Free Software Foundation.
15   - *
  15 + *
16 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 19 * details.
20   - *
  20 + *
21 21 * You should have received a copy of the GNU General Public License
22 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23   - *
24   - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  23 + *
  24 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
25 25 * California 94120-7775, or email info@knowledgetree.com.
26   - *
  26 + *
27 27 * The interactive user interfaces in modified source and object code versions
28 28 * of this program must display Appropriate Legal Notices, as required under
29 29 * Section 5 of the GNU General Public License version 3.
30   - *
  30 + *
31 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 32 * these Appropriate Legal Notices must retain the display of the "Powered by
33   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  33 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
34 34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
35   - * must display the words "Powered by KnowledgeTree" and retain the original
  35 + * must display the words "Powered by KnowledgeTree" and retain the original
36 36 * copyright notice.
37 37 * Contributor( s): ______________________________________
38 38 */
... ... @@ -149,35 +149,60 @@ class Session {
149 149 *
150 150 * @param int the userID to remove stale sessions for
151 151 */
152   - function removeStaleSessions() {
  152 + function removeStaleSessions($iUserId = null) {
153 153 global $default;
154 154 $time = time() - $default->sessionTimeout;
155 155  
  156 + // for web service sessions, we will expire after a month.
  157 + $monthPeriod = 30 * 24 * 60 * 60;
  158 + $wsTimeout = time() - $monthPeriod;
  159 +
  160 + if (is_null($iUserId))
  161 + {
  162 + $iUserId = $_SESSION['userID'];
  163 + // if the userid cannot be resolved, we will cleanup the entire sessions table
  164 + if (empty($iUserId))
  165 + {
  166 + $iUserId = 0;
  167 + }
  168 + }
  169 +
156 170 $sTable = KTUtil::getTableName('sessions');
  171 + $mintime = formatDateTime($time);
  172 + $mintime2 = formatDateTime($wsTimeout);
157 173 $aQuery = array(
158   - sprintf('SELECT id, lastused, user_id FROM %s WHERE lastused <= ?', $sTable),
159   - array(formatDateTime($time)),
  174 + sprintf("SELECT id, lastused, apptype FROM %s WHERE (user_id = $iUserId OR $iUserId = 0) AND ( (lastused <= '$mintime' and apptype == 'webapp') or (lastused <= '$mintime2' and apptype !='webapp') )", $sTable)
160 175 );
161 176  
162 177 $aSessions = DBUtil::getResultArray($aQuery);
  178 + $sSessionId = session_id();
  179 +
  180 + $deleteIds = array();
163 181  
164 182 foreach ($aSessions as $aSessionData) {
165 183 $iId = $aSessionData['id'];
166 184 $dLastUsed = $aSessionData['lastused'];
167   - $iUserId = $aSessionData['user_id'];
168 185 $iTime = strtotime($dLastUsed);
169   - $iTime = $iTime + $default->sessionTimeout;
  186 +
  187 + $iTime = $iTime + ($aSessionData['apptype'] == 'ws')?$monthPeriod:$default->sessionTimeout;
170 188 $aParams = array(
171 189 'userid' => $iUserId,
172 190 'datetime' => formatDateTime($iTime),
173 191 'actionnamespace' => 'ktcore.user_history.timeout',
174 192 'comments' => 'Session timed out',
175   - 'sessionid' => $_SESSION['sessionID'],
  193 + 'sessionid' => $sSessionId,
176 194 );
177 195 require_once(KT_LIB_DIR . '/users/userhistory.inc.php');
178 196 $res = KTUserHistory::createFromArray($aParams);
179 197  
180   - DBUtil::whereDelete($sTable, array('id' => $iId));
  198 + $deleteIds[] = $iId;
  199 + }
  200 +
  201 + if (!empty($deleteIds))
  202 + {
  203 + $deleteIds = implode(',',$deleteIds);
  204 + $sql = "delete from active_sessions where id in ($deleteIds)";
  205 + DBUtil::runQuery($sql);
181 206 }
182 207 }
183 208  
... ...