mirror of
https://github.com/rejetto/hfs2.git
synced 2025-12-19 18:13:46 +01:00
fix: sessions not expiring
This commit is contained in:
parent
8ff8a9ca22
commit
82de213059
132
main.pas
132
main.pas
@ -29,10 +29,11 @@ uses
|
|||||||
Windows, Messages, SysUtils, Forms, Menus, Graphics, Controls, ComCtrls, Dialogs, math,
|
Windows, Messages, SysUtils, Forms, Menus, Graphics, Controls, ComCtrls, Dialogs, math,
|
||||||
registry, ExtCtrls, shellapi, ImgList, ToolWin, StdCtrls, strutils, AppEvnts, types,
|
registry, ExtCtrls, shellapi, ImgList, ToolWin, StdCtrls, strutils, AppEvnts, types,
|
||||||
winsock, clipbrd, shlobj, activex, Buttons, FileCtrl, dateutils, iniFiles, Classes,
|
winsock, clipbrd, shlobj, activex, Buttons, FileCtrl, dateutils, iniFiles, Classes,
|
||||||
|
System.ImageList, system.Generics.Collections,
|
||||||
// 3rd part libs. ensure you have all of these, the same version reported in dev-notes.txt
|
// 3rd part libs. ensure you have all of these, the same version reported in dev-notes.txt
|
||||||
OverbyteIcsWSocket, OverbyteIcsHttpProt, OverbyteicsMD5, GIFimage, regexpr, OverbyteIcsZLibHigh, OverbyteIcsZLibObj,
|
OverbyteIcsWSocket, OverbyteIcsHttpProt, OverbyteicsMD5, GIFimage, regexpr, OverbyteIcsZLibHigh, OverbyteIcsZLibObj,
|
||||||
// rejetto libs
|
// rejetto libs
|
||||||
HSlib, traylib, monoLib, progFrmLib, classesLib, System.ImageList;
|
HSlib, traylib, monoLib, progFrmLib, classesLib;
|
||||||
|
|
||||||
const
|
const
|
||||||
VERSION = '2.4rc5';
|
VERSION = '2.4rc5';
|
||||||
@ -290,6 +291,19 @@ type
|
|||||||
size: int64;
|
size: int64;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Tsession = class
|
||||||
|
vars: THashedStringList;
|
||||||
|
created, ttl, expires: Tdatetime;
|
||||||
|
public
|
||||||
|
id: string;
|
||||||
|
constructor create(const sid:string='');
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure setVar(const k,v:string);
|
||||||
|
function getVar(const k:string):string;
|
||||||
|
procedure keepAlive();
|
||||||
|
end;
|
||||||
|
Tsessions = Tdictionary<string,Tsession>;
|
||||||
|
|
||||||
TconnData = class // data associated to a client connection
|
TconnData = class // data associated to a client connection
|
||||||
private
|
private
|
||||||
FlastFile: Tfile;
|
FlastFile: Tfile;
|
||||||
@ -337,8 +351,7 @@ type
|
|||||||
bytes: integer;
|
bytes: integer;
|
||||||
since: Tdatetime;
|
since: Tdatetime;
|
||||||
end;
|
end;
|
||||||
sessionID: string;
|
session: Tsession;
|
||||||
session,
|
|
||||||
vars, // defined by {.set.}
|
vars, // defined by {.set.}
|
||||||
urlvars, // as $_GET in php
|
urlvars, // as $_GET in php
|
||||||
postVars // as $_POST in php
|
postVars // as $_POST in php
|
||||||
@ -352,8 +365,6 @@ type
|
|||||||
property lastFile:Tfile read FlastFile write setLastFile;
|
property lastFile:Tfile read FlastFile write setLastFile;
|
||||||
constructor create(conn:ThttpConn);
|
constructor create(conn:ThttpConn);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function sessionGet(k:string):string;
|
|
||||||
procedure sessionSet(k, v:string);
|
|
||||||
procedure disconnect(reason:string);
|
procedure disconnect(reason:string);
|
||||||
procedure logout();
|
procedure logout();
|
||||||
end; // Tconndata
|
end; // Tconndata
|
||||||
@ -1083,7 +1094,7 @@ uses
|
|||||||
var
|
var
|
||||||
globalLimiter: TspeedLimiter;
|
globalLimiter: TspeedLimiter;
|
||||||
ip2obj: THashedStringList;
|
ip2obj: THashedStringList;
|
||||||
sessions: THashedStringList;
|
sessions: Tsessions;
|
||||||
addToFolder: string; // default folder where to add items from the command line
|
addToFolder: string; // default folder where to add items from the command line
|
||||||
lastDialogFolder: string; // stores last for open dialog, to make it persistent
|
lastDialogFolder: string; // stores last for open dialog, to make it persistent
|
||||||
clock: integer; // program ticks (tenths of second)
|
clock: integer; // program ticks (tenths of second)
|
||||||
@ -2257,6 +2268,53 @@ if assigned(mainFrm) then
|
|||||||
mainfrm.visible:=userInteraction.bakVisible;
|
mainfrm.visible:=userInteraction.bakVisible;
|
||||||
end; // reenableUserInteraction
|
end; // reenableUserInteraction
|
||||||
|
|
||||||
|
|
||||||
|
function getNewSID():string;
|
||||||
|
begin result:=replaceStr(base64encode(str_(now())+str_(random())), '=','') end;
|
||||||
|
|
||||||
|
constructor Tsession.create(const sid:string='');
|
||||||
|
begin
|
||||||
|
id:=sid;
|
||||||
|
if id = '' then
|
||||||
|
id:=getNewSID();
|
||||||
|
sessions.Add(id, self);
|
||||||
|
created:=now();
|
||||||
|
ttl:=1; // days
|
||||||
|
keepAlive();
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor Tsession.Destroy;
|
||||||
|
var
|
||||||
|
o: Tobject;
|
||||||
|
cd: TconnData;
|
||||||
|
begin
|
||||||
|
for o in srv.conns do
|
||||||
|
begin
|
||||||
|
cd:=ThttpConn(o).data;
|
||||||
|
if cd.session = self then
|
||||||
|
cd.session:=NIL;
|
||||||
|
end;
|
||||||
|
sessions.remove(id);
|
||||||
|
freeAndNIL(vars);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Tsession.keepAlive();
|
||||||
|
begin expires:=now() + ttl end;
|
||||||
|
|
||||||
|
function Tsession.getVar(const k:string):string;
|
||||||
|
begin
|
||||||
|
try result:=vars.values[k];
|
||||||
|
except result:=''
|
||||||
|
end;
|
||||||
|
end; // sessionGet
|
||||||
|
|
||||||
|
procedure Tsession.setVar(const k, v:string);
|
||||||
|
begin
|
||||||
|
if vars= NIL then
|
||||||
|
vars:=THashedStringList.create;
|
||||||
|
vars.addPair(k,v);
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TconnData.create(conn:ThttpConn);
|
constructor TconnData.create(conn:ThttpConn);
|
||||||
begin
|
begin
|
||||||
conn.data:=self;
|
conn.data:=self;
|
||||||
@ -2304,29 +2362,11 @@ end; // disconnect
|
|||||||
procedure TconnData.logout();
|
procedure TconnData.logout();
|
||||||
begin
|
begin
|
||||||
freeAndNIL(session);
|
freeAndNIL(session);
|
||||||
sessions.delete(sessions.IndexOf(sessionID));
|
|
||||||
sessionID:='';
|
|
||||||
usr:='';
|
usr:='';
|
||||||
pwd:='';
|
pwd:='';
|
||||||
conn.delCookie(SESSION_COOKIE);
|
conn.delCookie(SESSION_COOKIE);
|
||||||
end; // logout
|
end; // logout
|
||||||
|
|
||||||
function Tconndata.sessionGet(k:string):string;
|
|
||||||
begin
|
|
||||||
try result:=session.values[k];
|
|
||||||
except result:='' end;
|
|
||||||
end; // sessionGet
|
|
||||||
|
|
||||||
procedure Tconndata.sessionSet(k, v:string);
|
|
||||||
begin
|
|
||||||
if session = NIL then
|
|
||||||
begin
|
|
||||||
session:=THashedStringList.create;
|
|
||||||
sessions.addObject(sessionID, session);
|
|
||||||
end;
|
|
||||||
session.values[k]:=v;
|
|
||||||
end; // sessionSet
|
|
||||||
|
|
||||||
// we'll automatically free and previous temporary object
|
// we'll automatically free and previous temporary object
|
||||||
procedure TconnData.setLastFile(f:Tfile);
|
procedure TconnData.setLastFile(f:Tfile);
|
||||||
begin
|
begin
|
||||||
@ -4479,9 +4519,6 @@ else if tplLast <> 0 then
|
|||||||
end;
|
end;
|
||||||
end; // keepTplUpdated
|
end; // keepTplUpdated
|
||||||
|
|
||||||
function getNewSID():string;
|
|
||||||
begin result:=replaceStr(base64encode(str_(now())+str_(random())), '=','') end;
|
|
||||||
|
|
||||||
procedure setNewTplFile(fn:string);
|
procedure setNewTplFile(fn:string);
|
||||||
begin
|
begin
|
||||||
tplFilename:=fn;
|
tplFilename:=fn;
|
||||||
@ -4825,21 +4862,29 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure sessionSetup();
|
procedure sessionSetup();
|
||||||
|
var
|
||||||
|
sid: string;
|
||||||
begin
|
begin
|
||||||
if (data = NIL) or assigned(data.session) then exit;
|
if data = NIL then
|
||||||
data.sessionID:=conn.getCookie(SESSION_COOKIE);
|
exit;
|
||||||
if data.sessionID = '' then
|
if data.session = NIL then
|
||||||
begin
|
begin
|
||||||
data.sessionID:=getNewSID();
|
sid:=conn.getCookie(SESSION_COOKIE);
|
||||||
conn.setCookie(SESSION_COOKIE, data.sessionID, ['path','/'], 'HttpOnly'); // the session is site-wide, even if this request was related to a folder
|
if sid = '' then
|
||||||
|
begin
|
||||||
|
data.session:=Tsession.create();
|
||||||
|
conn.setCookie(SESSION_COOKIE, data.session.id, ['path','/'], 'HttpOnly'); // the session is site-wide, even if this request was related to a folder
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
try data.session:=sessions.objects[sessions.indexOf(data.sessionID)] as ThashedStringList
|
try data.session:=sessions[sid]
|
||||||
except end;
|
except data.session:=Tsession.create(sid) // probably expired
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
data.session.keepAlive();
|
||||||
if data.usr = '' then
|
if data.usr = '' then
|
||||||
begin
|
begin
|
||||||
data.usr:=data.sessionGet('user');
|
data.usr:=data.session.getVar('user');
|
||||||
data.pwd:=data.sessionGet('password');
|
data.pwd:=data.session.getVar('password');
|
||||||
end;
|
end;
|
||||||
if (data.usr = '') and (conn.request.user > '') then
|
if (data.usr = '') and (conn.request.user > '') then
|
||||||
begin
|
begin
|
||||||
@ -5229,17 +5274,17 @@ var
|
|||||||
In such case we would not be able to calculate pwd+sessionID because we'd had no clear pwd.
|
In such case we would not be able to calculate pwd+sessionID because we'd had no clear pwd.
|
||||||
By relying on md5(pwd) instead of pwd, we will avoid such problem. }
|
By relying on md5(pwd) instead of pwd, we will avoid such problem. }
|
||||||
s:=data.postVars.values['__PASSWORD_MD5'];
|
s:=data.postVars.values['__PASSWORD_MD5'];
|
||||||
if (s > '') and (s = strMD5(strMD5(data.account.pwd)+data.sessionID))
|
if (s > '') and (s = strMD5(strMD5(data.account.pwd)+data.session.id))
|
||||||
or (data.postVars.values['__PASSWORD'] = data.account.pwd) then
|
or (data.postVars.values['__PASSWORD'] = data.account.pwd) then
|
||||||
begin
|
begin
|
||||||
s:='ok';
|
s:='ok';
|
||||||
data.pwd:=data.account.pwd;
|
data.pwd:=data.account.pwd;
|
||||||
data.sessionSet('user', data.usr);
|
data.session.setVar('user', data.usr);
|
||||||
data.sessionSet('password', data.pwd);
|
data.session.setVar('password', data.pwd);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
s:='bad password';
|
s:='bad password'; //TODO shouldn't this change http code?
|
||||||
data.account:=NIL;
|
data.account:=NIL;
|
||||||
data.usr:='';
|
data.usr:='';
|
||||||
end;
|
end;
|
||||||
@ -7740,7 +7785,12 @@ var
|
|||||||
end; // every10minutes
|
end; // every10minutes
|
||||||
|
|
||||||
procedure everyMinute();
|
procedure everyMinute();
|
||||||
|
var
|
||||||
|
sess: Tsession;
|
||||||
begin
|
begin
|
||||||
|
for sess in sessions.values do
|
||||||
|
if now_ > sess.expires then
|
||||||
|
sess.free;
|
||||||
if updateDailyChk.Checked then
|
if updateDailyChk.Checked then
|
||||||
autoCheckUpdates();
|
autoCheckUpdates();
|
||||||
// purge icons older than 5 minutes, because sometimes icons change
|
// purge icons older than 5 minutes, because sometimes icons change
|
||||||
@ -12439,7 +12489,7 @@ filelistTpl:=Ttpl.create(getRes('filelistTpl'));
|
|||||||
globalLimiter:=TspeedLimiter.create();
|
globalLimiter:=TspeedLimiter.create();
|
||||||
ip2obj:=THashedStringList.create();
|
ip2obj:=THashedStringList.create();
|
||||||
etags:=THashedStringList.create();
|
etags:=THashedStringList.create();
|
||||||
sessions:=THashedStringList.create();
|
sessions:=Tsessions.create();
|
||||||
ipsEverConnected:=THashedStringList.create();
|
ipsEverConnected:=THashedStringList.create();
|
||||||
ipsEverConnected.sorted:=TRUE;
|
ipsEverConnected.sorted:=TRUE;
|
||||||
ipsEverConnected.duplicates:=dupIgnore;
|
ipsEverConnected.duplicates:=dupIgnore;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user