summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristopherm <christopherm@4979c152-3d1c-0410-bac9-87ea11338e46>2006-11-21 05:38:28 +0000
committerchristopherm <christopherm@4979c152-3d1c-0410-bac9-87ea11338e46>2006-11-21 05:38:28 +0000
commit4380e21c81cb00190bb2b0591cf10fdf2ad8238e (patch)
treec3745255523df1fc7cf9a06ed5d44e7d6787697f
parentb4b79c241c55438614a36cceb6b620907f1c3105 (diff)
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.
git-svn-id: https://ledger-smb.svn.sourceforge.net/svnroot/ledger-smb/branches/1.2@675 4979c152-3d1c-0410-bac9-87ea11338e46
-rwxr-xr-xLedgerSMB/Session/DB.pm98
-rwxr-xr-xbin/menu.pl2
-rwxr-xr-xlocale/html/splash.html26
-rwxr-xr-xlocale/splash.html26
-rwxr-xr-xsql/Pg-central.sql4
5 files changed, 131 insertions, 25 deletions
diff --git a/LedgerSMB/Session/DB.pm b/LedgerSMB/Session/DB.pm
index 8b1d20f0..f75be4b5 100755
--- a/LedgerSMB/Session/DB.pm
+++ b/LedgerSMB/Session/DB.pm
@@ -31,19 +31,32 @@ package Session;
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;
@@ -55,24 +68,39 @@ sub session_check {
$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/[^a-zA-Z0-9@.-]//g;
+ $login =~ s/[^a-zA-Z0-9._+@-]//g;
+
+ 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;
- if($sessionLogin eq $login){
- $updateAge->execute($sessionid) || $form->dberror(__FILE__.':'.__LINE__.': Updating session age: ');
+ #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_check {
}
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 @@ sub session_create {
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/[^a-zA-Z0-9@.-]//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,13 +168,16 @@ sub session_create {
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
@@ -144,13 +190,18 @@ sub session_destroy {
my ($form) = @_;
my $login = $form->{login};
- $login =~ s/[^a-zA-Z0-9@.-]//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 @@ sub password_check {
my ($form, $username, $password) = @_;
+ $username =~ s/[^a-zA-Z0-9._+@-]//g;
+
# use the central database handle
my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
@@ -188,7 +241,8 @@ sub password_check {
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;
diff --git a/bin/menu.pl b/bin/menu.pl
index c44da8be..c5d3a7f7 100755
--- a/bin/menu.pl
+++ b/bin/menu.pl
@@ -57,7 +57,7 @@ sub display {
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>
|;
diff --git a/locale/html/splash.html b/locale/html/splash.html
new file mode 100755
index 00000000..18719b5c
--- /dev/null
+++ b/locale/html/splash.html
@@ -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>
diff --git a/locale/splash.html b/locale/splash.html
new file mode 100755
index 00000000..18719b5c
--- /dev/null
+++ b/locale/splash.html
@@ -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>
diff --git a/sql/Pg-central.sql b/sql/Pg-central.sql
index 50904801..15c16ad7 100755
--- a/sql/Pg-central.sql
+++ b/sql/Pg-central.sql
@@ -69,10 +69,10 @@ COMMENT ON FUNCTION update_user(int4,text) IS $$ Takes int4 which is users.id an
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;