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,31 +7,31 @@
7 * Document Management Made Simple 7 * Document Management Made Simple
8 * Copyright (C) 2008 KnowledgeTree Inc. 8 * Copyright (C) 2008 KnowledgeTree Inc.
9 * Portions copyright The Jam Warehouse Software (Pty) Limited 9 * Portions copyright The Jam Warehouse Software (Pty) Limited
10 - * 10 + *
11 * This program is free software; you can redistribute it and/or modify it under 11 * This program is free software; you can redistribute it and/or modify it under
12 * the terms of the GNU General Public License version 3 as published by the 12 * the terms of the GNU General Public License version 3 as published by the
13 * Free Software Foundation. 13 * Free Software Foundation.
14 - * 14 + *
15 * This program is distributed in the hope that it will be useful, but WITHOUT 15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 * details. 18 * details.
19 - * 19 + *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 * California 94120-7775, or email info@knowledgetree.com. 24 * California 94120-7775, or email info@knowledgetree.com.
25 - * 25 + *
26 * The interactive user interfaces in modified source and object code versions 26 * The interactive user interfaces in modified source and object code versions
27 * of this program must display Appropriate Legal Notices, as required under 27 * of this program must display Appropriate Legal Notices, as required under
28 * Section 5 of the GNU General Public License version 3. 28 * Section 5 of the GNU General Public License version 3.
29 - * 29 + *
30 * In accordance with Section 7(b) of the GNU General Public License version 3, 30 * In accordance with Section 7(b) of the GNU General Public License version 3,
31 * these Appropriate Legal Notices must retain the display of the "Powered by 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 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 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 * copyright notice. 35 * copyright notice.
36 * Contributor( s): ______________________________________ 36 * Contributor( s): ______________________________________
37 * 37 *
@@ -124,10 +124,6 @@ class KTAPI_UserSession extends KTAPI_Session @@ -124,10 +124,6 @@ class KTAPI_UserSession extends KTAPI_Session
124 $this->active = true; 124 $this->active = true;
125 } 125 }
126 126
127 -  
128 -  
129 -  
130 -  
131 /** 127 /**
132 * This resolves the user's ip 128 * This resolves the user's ip
133 * 129 *
@@ -164,18 +160,18 @@ class KTAPI_UserSession extends KTAPI_Session @@ -164,18 +160,18 @@ class KTAPI_UserSession extends KTAPI_Session
164 * @static 160 * @static
165 * @param User $user 161 * @param User $user
166 */ 162 */
167 - function _check_session(&$user) 163 + function _check_session(&$user, $ip, $app)
168 { 164 {
169 $user_id = $user->getId(); 165 $user_id = $user->getId();
170 166
171 - Session::removeStaleSessions(); 167 + Session::removeStaleSessions($user_id);
172 168
173 $config = &KTConfig::getSingleton(); 169 $config = &KTConfig::getSingleton();
174 $validateSession = $config->get('webservice/validateSessionCount', false); 170 $validateSession = $config->get('webservice/validateSessionCount', false);
175 171
176 if ($validateSession) 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 $row = DBUtil::getOneResult($sql); 175 $row = DBUtil::getOneResult($sql);
180 176
181 if (PEAR::isError($row)) 177 if (PEAR::isError($row))
@@ -193,18 +189,44 @@ class KTAPI_UserSession extends KTAPI_Session @@ -193,18 +189,44 @@ class KTAPI_UserSession extends KTAPI_Session
193 } 189 }
194 190
195 $session = session_id(); 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 return array($session,$sessionid); 231 return array($session,$sessionid);
210 } 232 }
@@ -219,7 +241,7 @@ class KTAPI_UserSession extends KTAPI_Session @@ -219,7 +241,7 @@ class KTAPI_UserSession extends KTAPI_Session
219 * @param string $password 241 * @param string $password
220 * @return KTAPI_Session 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 $this->active=false; 246 $this->active=false;
225 if ( empty($username) ) 247 if ( empty($username) )
@@ -247,11 +269,11 @@ class KTAPI_UserSession extends KTAPI_Session @@ -247,11 +269,11 @@ class KTAPI_UserSession extends KTAPI_Session
247 269
248 if (is_null($ip)) 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 if (PEAR::isError($result)) 278 if (PEAR::isError($result))
257 { 279 {
@@ -273,9 +295,9 @@ class KTAPI_UserSession extends KTAPI_Session @@ -273,9 +295,9 @@ class KTAPI_UserSession extends KTAPI_Session
273 * @param string $ip 295 * @param string $ip
274 * @return KTAPI_Session 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 if (!empty($ip)) 301 if (!empty($ip))
280 { 302 {
281 $sql .= " AND ip='$ip'"; 303 $sql .= " AND ip='$ip'";
@@ -296,13 +318,10 @@ class KTAPI_UserSession extends KTAPI_Session @@ -296,13 +318,10 @@ class KTAPI_UserSession extends KTAPI_Session
296 return new KTAPI_Error(KTAPI_ERROR_USER_INVALID, $user); 318 return new KTAPI_Error(KTAPI_ERROR_USER_INVALID, $user);
297 } 319 }
298 320
299 -  
300 -  
301 $now=date('Y-m-d H:i:s'); 321 $now=date('Y-m-d H:i:s');
302 $sql = "UPDATE active_sessions SET lastused='$now' WHERE id=$sessionid"; 322 $sql = "UPDATE active_sessions SET lastused='$now' WHERE id=$sessionid";
303 DBUtil::runQuery($sql); 323 DBUtil::runQuery($sql);
304 324
305 -  
306 if ($user->isAnonymous()) 325 if ($user->isAnonymous())
307 $session = &new KTAPI_AnonymousSession($ktapi, $user, $session, $sessionid, $ip); 326 $session = &new KTAPI_AnonymousSession($ktapi, $user, $session, $sessionid, $ip);
308 else 327 else
@@ -333,7 +352,7 @@ class KTAPI_UserSession extends KTAPI_Session @@ -333,7 +352,7 @@ class KTAPI_UserSession extends KTAPI_Session
333 352
334 class KTAPI_AnonymousSession extends KTAPI_UserSession 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 $user =& User::get(-2); 357 $user =& User::get(-2);
339 if (is_null($user) || PEAR::isError($user) || ($user === false) || !$user->isAnonymous()) 358 if (is_null($user) || PEAR::isError($user) || ($user === false) || !$user->isAnonymous())
@@ -357,7 +376,7 @@ class KTAPI_AnonymousSession extends KTAPI_UserSession @@ -357,7 +376,7 @@ class KTAPI_AnonymousSession extends KTAPI_UserSession
357 //$ip = KTAPI_Session::resolveIP(); 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 if (PEAR::isError($sessionid)) 380 if (PEAR::isError($sessionid))
362 { 381 {
363 return $sessionid; 382 return $sessionid;
ktapi/ktapi.inc.php
@@ -8,31 +8,31 @@ @@ -8,31 +8,31 @@
8 * Document Management Made Simple 8 * Document Management Made Simple
9 * Copyright (C) 2008 KnowledgeTree Inc. 9 * Copyright (C) 2008 KnowledgeTree Inc.
10 * Portions copyright The Jam Warehouse Software (Pty) Limited 10 * Portions copyright The Jam Warehouse Software (Pty) Limited
11 - * 11 + *
12 * This program is free software; you can redistribute it and/or modify it under 12 * This program is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License version 3 as published by the 13 * the terms of the GNU General Public License version 3 as published by the
14 * Free Software Foundation. 14 * Free Software Foundation.
15 - * 15 + *
16 * This program is distributed in the hope that it will be useful, but WITHOUT 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * details. 19 * details.
20 - * 20 + *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 * California 94120-7775, or email info@knowledgetree.com. 25 * California 94120-7775, or email info@knowledgetree.com.
26 - * 26 + *
27 * The interactive user interfaces in modified source and object code versions 27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under 28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU General Public License version 3. 29 * Section 5 of the GNU General Public License version 3.
30 - * 30 + *
31 * In accordance with Section 7(b) of the GNU General Public License version 3, 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by 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 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 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 * copyright notice. 36 * copyright notice.
37 * Contributor( s): ______________________________________ 37 * Contributor( s): ______________________________________
38 * 38 *
@@ -219,14 +219,14 @@ class KTAPI @@ -219,14 +219,14 @@ class KTAPI
219 * @param string $session 219 * @param string $session
220 * @return KTAPI_Session 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 if (!is_null($this->session)) 224 if (!is_null($this->session))
225 { 225 {
226 return new PEAR_Error('A session is currently active.'); 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 if (is_null($session) || PEAR::isError($session)) 231 if (is_null($session) || PEAR::isError($session))
232 { 232 {
@@ -245,14 +245,14 @@ class KTAPI @@ -245,14 +245,14 @@ class KTAPI
245 * @param string $password 245 * @param string $password
246 * @return KTAPI_Session 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 if (!is_null($this->session)) 250 if (!is_null($this->session))
251 { 251 {
252 return new PEAR_Error('A session is currently active.'); 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 if (is_null($session)) 256 if (is_null($session))
257 { 257 {
258 return new PEAR_Error('Session is null.'); 258 return new PEAR_Error('Session is null.');
lib/session/Session.inc
@@ -8,31 +8,31 @@ @@ -8,31 +8,31 @@
8 * Document Management Made Simple 8 * Document Management Made Simple
9 * Copyright (C) 2008 KnowledgeTree Inc. 9 * Copyright (C) 2008 KnowledgeTree Inc.
10 * Portions copyright The Jam Warehouse Software (Pty) Limited 10 * Portions copyright The Jam Warehouse Software (Pty) Limited
11 - * 11 + *
12 * This program is free software; you can redistribute it and/or modify it under 12 * This program is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License version 3 as published by the 13 * the terms of the GNU General Public License version 3 as published by the
14 * Free Software Foundation. 14 * Free Software Foundation.
15 - * 15 + *
16 * This program is distributed in the hope that it will be useful, but WITHOUT 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 * details. 19 * details.
20 - * 20 + *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 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 * California 94120-7775, or email info@knowledgetree.com. 25 * California 94120-7775, or email info@knowledgetree.com.
26 - * 26 + *
27 * The interactive user interfaces in modified source and object code versions 27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under 28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU General Public License version 3. 29 * Section 5 of the GNU General Public License version 3.
30 - * 30 + *
31 * In accordance with Section 7(b) of the GNU General Public License version 3, 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by 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 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 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 * copyright notice. 36 * copyright notice.
37 * Contributor( s): ______________________________________ 37 * Contributor( s): ______________________________________
38 */ 38 */
@@ -149,35 +149,60 @@ class Session { @@ -149,35 +149,60 @@ class Session {
149 * 149 *
150 * @param int the userID to remove stale sessions for 150 * @param int the userID to remove stale sessions for
151 */ 151 */
152 - function removeStaleSessions() { 152 + function removeStaleSessions($iUserId = null) {
153 global $default; 153 global $default;
154 $time = time() - $default->sessionTimeout; 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 $sTable = KTUtil::getTableName('sessions'); 170 $sTable = KTUtil::getTableName('sessions');
  171 + $mintime = formatDateTime($time);
  172 + $mintime2 = formatDateTime($wsTimeout);
157 $aQuery = array( 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 $aSessions = DBUtil::getResultArray($aQuery); 177 $aSessions = DBUtil::getResultArray($aQuery);
  178 + $sSessionId = session_id();
  179 +
  180 + $deleteIds = array();
163 181
164 foreach ($aSessions as $aSessionData) { 182 foreach ($aSessions as $aSessionData) {
165 $iId = $aSessionData['id']; 183 $iId = $aSessionData['id'];
166 $dLastUsed = $aSessionData['lastused']; 184 $dLastUsed = $aSessionData['lastused'];
167 - $iUserId = $aSessionData['user_id'];  
168 $iTime = strtotime($dLastUsed); 185 $iTime = strtotime($dLastUsed);
169 - $iTime = $iTime + $default->sessionTimeout; 186 +
  187 + $iTime = $iTime + ($aSessionData['apptype'] == 'ws')?$monthPeriod:$default->sessionTimeout;
170 $aParams = array( 188 $aParams = array(
171 'userid' => $iUserId, 189 'userid' => $iUserId,
172 'datetime' => formatDateTime($iTime), 190 'datetime' => formatDateTime($iTime),
173 'actionnamespace' => 'ktcore.user_history.timeout', 191 'actionnamespace' => 'ktcore.user_history.timeout',
174 'comments' => 'Session timed out', 192 'comments' => 'Session timed out',
175 - 'sessionid' => $_SESSION['sessionID'], 193 + 'sessionid' => $sSessionId,
176 ); 194 );
177 require_once(KT_LIB_DIR . '/users/userhistory.inc.php'); 195 require_once(KT_LIB_DIR . '/users/userhistory.inc.php');
178 $res = KTUserHistory::createFromArray($aParams); 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