[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb: [675] branches/1.2



Revision: 675
          http://svn.sourceforge.net/ledger-smb/?rev=675&view=rev
Author:   christopherm
Date:     2006-11-20 21:38:28 -0800 (Mon, 20 Nov 2006)

Log Message:
-----------
Moving to 1.2: Adding transaction_id. This will require an update to the session table, please drop table session and recreate with the create statement in Pg-central.sql. This is an anti-hijacking tool and something that will prevent users from double posting data.

Modified Paths:
--------------
    branches/1.2/LedgerSMB/Session/DB.pm
    branches/1.2/bin/menu.pl
    branches/1.2/sql/Pg-central.sql

Added Paths:
-----------
    branches/1.2/locale/html/
    branches/1.2/locale/splash.html

Modified: branches/1.2/LedgerSMB/Session/DB.pm
===================================================================
--- branches/1.2/LedgerSMB/Session/DB.pm	2006-11-21 05:22:23 UTC (rev 674)
+++ branches/1.2/LedgerSMB/Session/DB.pm	2006-11-21 05:38:28 UTC (rev 675)
@@ -31,20 +31,33 @@
 
 sub session_check {
 
+	use Time::HiRes qw(gettimeofday);
+
 	my ($cookie, $form) = @_;
-	my ($sessionid, $token) = split /:/, $cookie;
+	my ($sessionID, $transactionID, $token) = split /:/, $cookie;
 
 	# use the central database handle
 	my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH}; 
 
-	my $checkQuery = $dbh->prepare("SELECT sl_login FROM session WHERE session_id = ? AND token = ? AND last_used > now() - ?::interval");
+	my $checkQuery = $dbh->prepare("SELECT u.username, s.transaction_id 
+									  FROM session as s, users as u 
+									 WHERE s.session_id = ? 
+									   AND s.token = ?
+									   AND s.users_id = u.id
+									   AND s.last_used > now() - ?::interval");
 
-	my $updateAge = $dbh->prepare("UPDATE session SET last_used = now() WHERE session_id = ?;");
+	my $updateAge = $dbh->prepare("UPDATE session 
+									  SET last_used = now(),
+										  transaction_id = ?
+									WHERE session_id = ?;");
 
 	#must be an integer
-	$sessionid =~ s/[^0-9]//g;
-	$sessionid = int $sessionid;
+	$sessionID =~ s/[^0-9]//g;
+	$sessionID = int $sessionID;
 
+	$transactionID =~ s/[^0-9]//g;
+	$transactionID = int $transactionID;
+
 	#must be 32 chars long and contain hex chars
 	$token =~ s/[^0-9a-f]//g;
 	$token = substr($token, 0, 32);
@@ -55,24 +68,39 @@
 		$timeout = "$myconfig{timeout} seconds";
 	}
 
-	$checkQuery->execute($sessionid, $token, $timeout) 
+	$checkQuery->execute($sessionID, $token, $timeout) 
 		|| $form->dberror(__FILE__.':'.__LINE__.': Looking for session: ');
 	my $sessionValid = $checkQuery->rows;
 
 	if($sessionValid){
 
 		#user has a valid session cookie, now check the user
-		my ($sessionLogin) = $checkQuery->fetchrow_array;
+		my ($sessionLogin, $sessionTransaction) = $checkQuery->fetchrow_array;
 
 		my $login = $form->{login};
-		$login =~ s/..hidden..//g;
+		$login =~ s/..hidden..//g;
 
-		if($sessionLogin eq $login){
-			$updateAge->execute($sessionid) || $form->dberror(__FILE__.':'.__LINE__.': Updating session age: ');
+		if(($sessionLogin eq $login) and ($sessionTransaction eq $transactionID)){
+
+			#microseconds are more than random enough for transaction_id
+			my ($ignore, $newTransactionID) = gettimeofday();
+
+			$newTransactionID = int $newTransactionID;
+	
+			$updateAge->execute($newTransactionID, $sessionID) 
+				|| $form->dberror(__FILE__.':'.__LINE__.': Updating session age: ');
+
+			$newCookieValue = $sessionID . ':'.$newTransactionID.':' . $token;
+
+			#now update the cookie in the browser
+			print qq|Set-Cookie: LedgerSMB=$newCookieValue; path=/;\n|;
 			return 1;
 
 		} else {
-			#something's wrong, they have the cookie, but wrong user. Hijack attempt?
+			#something's wrong, they have the cookie, but wrong user or the wrong transaction id. Hijack attempt?
+			#destroy the session
+			my $sessionDestroy = $dbh->prepare("");
+
 			#delete the cookie in the browser
 			print qq|Set-Cookie: LedgerSMB=; path=/;\n|;
 			return 0;
@@ -87,6 +115,13 @@
 }
 
 sub session_create {
+
+	use Time::HiRes qw(gettimeofday);
+
+	#microseconds are more than random enough for transaction_id
+	my ($ignore, $newTransactionID) = gettimeofday();
+	$newTransactionID = int $newTransactionID;
+
 	my ($form) = @_;
 
 	if (! $ENV{HTTP_HOST}){
@@ -98,26 +133,34 @@
 	my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH}; 
 
 	# TODO Change this to use %myconfig
-	my $deleteExisting = $dbh->prepare("DELETE FROM session WHERE sl_login = ? AND age(last_used) > ?::interval");  
+	my $deleteExisting = $dbh->prepare("DELETE FROM session
+											  USING users
+											  WHERE users.username = ?
+												AND users.id = session.users_id
+												AND age(last_used) > ?::interval");  
 
 	my $seedRandom = $dbh->prepare("SELECT setseed(?);");
 
 	my $fetchSequence = $dbh->prepare("SELECT nextval('session_session_id_seq'), md5(random());");
 	
-	my $createNew = $dbh->prepare("INSERT INTO session (session_id, sl_login, token) VALUES(?, ?, ?);");
+	my $createNew = $dbh->prepare("INSERT INTO session (session_id, users_id, token, transaction_id) 
+										VALUES(?, (SELECT id
+													 FROM users
+													WHERE username = ?), ?, ?);");
 
 
 	# this is assuming that $form->{login} is safe, which might be a bad assumption
 	# so, I'm going to remove some chars, which might make previously valid logins invalid
 	my $login = $form->{login};
-	$login =~ s/..hidden..//g;
+	$login =~ s/[^a-zA-Z0-9._+@'-]//g;
 
 	#delete any existing stale sessions with this login if they exist
 	if (!$myconfig{timeout}){
 	   $myconfig{timeout} = 86400;
 	}
 
-	$deleteExisting->execute($login, "$myconfig{timeout} seconds") || $form->dberror(__FILE__.':'.__LINE__.': Delete from session: ');
+	$deleteExisting->execute($login, "$myconfig{timeout} seconds") 
+		|| $form->dberror(__FILE__.':'.__LINE__.': Delete from session: ');
 
 	#doing the random stuff in the db so that LedgerSMB won't
 	#require a good random generator - maybe this should be reviewed, pgsql's isn't great either
@@ -125,14 +168,17 @@
 	my ($newSessionID, $newToken) = $fetchSequence->fetchrow_array;
 
 	#create a new session
-	$createNew->execute($newSessionID, $login, $newToken) || $form->dberror(__FILE__.':'.__LINE__.': Create new session: ');
+	$createNew->execute($newSessionID, $login, $newToken, $newTransactionID) 
+		|| $form->dberror(__FILE__.':'.__LINE__.': Create new session: ');
 
 	#reseed the random number generator
 	my $randomSeed = 1.0 * ('0.'. (time() ^ ($$ + ($$ <<15))));
-	$seedRandom->execute($randomSeed)|| $form->dberror(__FILE__.':'.__LINE__.': Reseed random generator: ');
 
-	$newCookieValue = $newSessionID . ':' . $newToken;
+	$seedRandom->execute($randomSeed) 
+		|| $form->dberror(__FILE__.':'.__LINE__.': Reseed random generator: ');
 
+	$newCookieValue = $newSessionID . ':'.$newTransactionID.':' . $newToken;
+
 	#now set the cookie in the browser
 	#TODO set domain from ENV, also set path to install path
 	print qq|Set-Cookie: LedgerSMB=$newCookieValue; path=/;\n|;
@@ -144,14 +190,19 @@
 	my ($form) = @_;
 
 	my $login = $form->{login};
-	$login =~ s/..hidden..//g;
+	$login =~ s/[^a-zA-Z0-9._+@'-]//g;
 
 	# use the central database handle
 	my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
 
-	my $deleteExisting = $dbh->prepare("DELETE FROM session WHERE sl_login = ?;");
-	$deleteExisting->execute($login) || $form->dberror(__FILE__.':'.__LINE__.': Delete from session: ');
+	my $deleteExisting = $dbh->prepare("DELETE FROM session 
+											  USING users
+											  WHERE users.username = ?
+												AND users.id = session.users_id;");
 
+	$deleteExisting->execute($login)
+		|| $form->dberror(__FILE__.':'.__LINE__.': Delete from session: ');
+
 	#delete the cookie in the browser
 	print qq|Set-Cookie: LedgerSMB=; path=/;\n|;
 
@@ -163,6 +214,8 @@
 
 	my ($form, $username, $password) = @_;
 
+	$username =~ s/..hidden..//g;
+
 	# use the central database handle
 	my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
 
@@ -188,7 +241,8 @@
 												 WHERE users_conf.id = users.id
 												   AND users.username = ?;");
 
-			$updatePassword->execute($password, $username) || $form->dberror(__FILE__.':'.__LINE__.': Converting password : ');
+			$updatePassword->execute($password, $username) 
+				|| $form->dberror(__FILE__.':'.__LINE__.': Converting password : ');
 
 			return 1;
 

Modified: branches/1.2/bin/menu.pl
===================================================================
--- branches/1.2/bin/menu.pl	2006-11-21 05:22:23 UTC (rev 674)
+++ branches/1.2/bin/menu.pl	2006-11-21 05:38:28 UTC (rev 675)
@@ -57,7 +57,7 @@
 		print qq|
 		<frameset cols="$menuwidth,*" border="1">
 			<frame name="acc_menu" src="menu.pl?login=$form->{login}&amp;sessionid=$form->{sessionid}&amp;action=acc_menu&amp;path=$form->{path}&amp;js=$form->{js}" />
-			<frame name="main_window" src="am.pl?login=$form->{login}&amp;sessionid=$form->{sessionid}&amp;action=$form->{main}&amp;path=$form->{path}" />
+			<frame name="main_window" src="locale/html/splash.html" />
 		</frameset>
 		</html>
 		|;

Copied: branches/1.2/locale/html (from rev 674, trunk/locale/html)

Copied: branches/1.2/locale/splash.html (from rev 674, trunk/locale/html/splash.html)
===================================================================
--- branches/1.2/locale/splash.html	                        (rev 0)
+++ branches/1.2/locale/splash.html	2006-11-21 05:38:28 UTC (rev 675)
@@ -0,0 +1,26 @@
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+		"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
+<head>
+	<title>LedgerSMB Splash page</title>
+	<meta http-equiv="Pragma" content="no-cache" />
+	<meta http-equiv="Expires" content="-1" />
+	<link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon" />
+	<link rel="stylesheet" href="../../css/ledger-smb.css" type="text/css" title="LedgerSMB stylesheet" />
+	<meta name="robots" content="noindex,nofollow" />
+</head>
+<body>
+<br /><br /><br />
+<center>
+<a href="http://www.ledgersmb.org/"; target="_blank"><img style="border: 1px solid #000000;" src="../../ledger-smb.png" width="200" height="100" border="0" alt="LedgerSMB Logo" /></a>
+<br /><br /><br />
+<table width="80%" border="0" cellpadding="0" cellspacing="0">
+<tr>
+	</td>
+	</td>
+</tr>
+</table>
+</center>
+</body>
+</html>

Modified: branches/1.2/sql/Pg-central.sql
===================================================================
--- branches/1.2/sql/Pg-central.sql	2006-11-21 05:22:23 UTC (rev 674)
+++ branches/1.2/sql/Pg-central.sql	2006-11-21 05:38:28 UTC (rev 675)
@@ -69,10 +69,10 @@
 
 CREATE TABLE session(
 session_id serial PRIMARY KEY,
-sl_login VARCHAR(50),
 token VARCHAR(32) CHECK(length(token) = 32),
 last_used TIMESTAMP default now(),
-users_id INTEGER  -- NOT NULL references users(id)
+users_id INTEGER NOT NULL references users(id),
+transaction_id INTEGER NOT NULL
 );
 
 commit;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.