399 lines
13 KiB
Plaintext
399 lines
13 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ BsKwdSchKvCttSchClient }
|
|
{ }
|
|
{ Copyright (C) 2023 kku }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit BsKwdSchKvCttSchClient;
|
|
|
|
interface
|
|
|
|
uses
|
|
Tocsg.ClientBase, System.SysUtils, System.Classes, Tocsg.Packet,
|
|
Winapi.Windows, Tocsg.Win32, CttSchDefine, FileService;
|
|
|
|
const
|
|
FILEMON_WRITEMON = 1;
|
|
FILEMON_WRITEBLOCK = 2;
|
|
FILEMON_DRM = 3;
|
|
|
|
type
|
|
TBsKwdSchKvCttSchClient = class(TTgClientBase)
|
|
private
|
|
dwExecuteTick_: DWORD;
|
|
bTerminated_: Boolean;
|
|
sKvPath_: String;
|
|
Mtx_: TTgMutex;
|
|
FileScanOpt_: TFileScanOpt;
|
|
|
|
ThdDelFiles_: TThdDelFiles;
|
|
ThdEncFiles_: TThdEncFiles;
|
|
protected
|
|
function GetConnected: Boolean; override;
|
|
procedure ConnectedEvent; override;
|
|
procedure DisconnectedEvent; override;
|
|
procedure ProcessRcvPacket(aRcv: IRcvPacket); override;
|
|
public
|
|
Constructor Create(aFileScanOpt: TFileScanOpt);
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
var
|
|
gKvKwdSch: TBsKwdSchKvCttSchClient = nil;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Exception, Tocsg.Strings, Tocsg.WndUtil, Tocsg.Path,
|
|
superobject, Tocsg.Json, Tocsg.Shell, Tocsg.KvFilter.adinfo, ManagerService,
|
|
GlobalDefine, ManagerModel, Tocsg.Safe, Tocsg.PCRE, ManagerCampaign,
|
|
Condition, Tocsg.Files;
|
|
|
|
const
|
|
DOC_HEADER_FMT = '<eCrmFormat>%s</eCrmFormat><eCrmClass>%s</eCrmClass>';
|
|
|
|
{ TBsKwdSchKvCttSchClient }
|
|
|
|
Constructor TBsKwdSchKvCttSchClient.Create(aFileScanOpt: TFileScanOpt);
|
|
begin
|
|
Inherited Create('', 0);
|
|
ASSERT(gKvKwdSch = nil);
|
|
gKvKwdSch := Self;
|
|
dwExecuteTick_ := 0;
|
|
bTerminated_ := false;
|
|
FileScanOpt_ := aFileScanOpt;
|
|
sKvPath_ := GetRunExePathDir + EXE_KVCTTSCH;
|
|
Mtx_ := TTgMutex.Create('Global\BsFileMonKv' + IntToStr(GetTickCount));
|
|
|
|
ThdDelFiles_ := TThdDelFiles.Create;
|
|
ThdEncFiles_ := TThdEncFiles.Create;
|
|
|
|
ThdDelFiles_.StartThread;
|
|
ThdEncFiles_.StartThread;
|
|
end;
|
|
|
|
Destructor TBsKwdSchKvCttSchClient.Destroy;
|
|
begin
|
|
gKvKwdSch := nil;
|
|
FreeAndNil(Mtx_);
|
|
bTerminated_ := true;
|
|
Inherited;
|
|
FreeAndNil(ThdEncFiles_);
|
|
FreeAndNil(ThdDelFiles_);
|
|
end;
|
|
|
|
function TBsKwdSchKvCttSchClient.GetConnected: Boolean;
|
|
|
|
{$IFDEF DEBUG}
|
|
procedure ConnectDebugCore;
|
|
var
|
|
hFind, hIpc: HWND;
|
|
begin
|
|
hFind := FindWindow('TDlgKvCttSchMain', nil);
|
|
if hFind <> 0 then
|
|
begin
|
|
hIpc := StrToInt64Def(ExtrNumStr(GetWindowCaption(hFind)), 0);
|
|
if hIpc <> 0 then
|
|
ConnectWnd(hIpc);
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
var
|
|
sParam: String;
|
|
O: ISuperObject;
|
|
begin
|
|
Result := Inherited;
|
|
|
|
if not Result and not bTerminated_ and (W2W_ <> nil) then
|
|
begin
|
|
if (GetTickCount - dwExecuteTick_) > 10000 then // 최소 10초에 한번만 실행 되도록함
|
|
begin
|
|
dwExecuteTick_ := GetTickCount;
|
|
|
|
{$IFDEF 1DEBUG}
|
|
if DebugHook <> 0 then
|
|
begin
|
|
ConnectDebugCore;
|
|
exit;
|
|
end;
|
|
{$ELSE}
|
|
if not FileExists(sKvPath_) then
|
|
begin
|
|
_Trace('Fail .. GetConnected() .. Not found "kv-exe"');
|
|
exit;
|
|
end;
|
|
|
|
if GetSelfWnd = 0 then
|
|
begin
|
|
_Trace('Fail .. GetConnected() .. GetSelfWnd()');
|
|
exit;
|
|
end;
|
|
|
|
O := SO;
|
|
O.I['CSTT'] := Integer(csttSchConnect);
|
|
O.S['Mtx'] := Mtx_.MutexName;
|
|
O.I['Tasker'] := GetSelfWnd;
|
|
O.O['Opt'] := TTgJson.ValueToJsonObject<TCttSchOpt>(FileScanOpt_.CttSchOpt);
|
|
O.I['CT'] := CUSTOMER_TYPE;
|
|
sParam := GetRunExePathDir + '$bfkso.dat';
|
|
if SaveJsonObjToFile(O, sParam) then
|
|
begin
|
|
ExecutePath(sKvPath_, Format('-p "%s"', [sParam]));
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBsKwdSchKvCttSchClient.ConnectedEvent;
|
|
begin
|
|
try
|
|
Inherited;
|
|
SetSendPauseState(false);
|
|
_Trace('Connected.', 3);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. ConnectedEvent()');
|
|
end;
|
|
end;
|
|
|
|
procedure TBsKwdSchKvCttSchClient.DisconnectedEvent;
|
|
begin
|
|
try
|
|
Inherited;
|
|
QSendPacket_.Clear;
|
|
|
|
_Trace('Disconnected', 3);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. DisconnectedEvent()');
|
|
end;
|
|
end;
|
|
|
|
procedure TBsKwdSchKvCttSchClient.ProcessRcvPacket(aRcv: IRcvPacket);
|
|
|
|
function GetEventToStr(nAction: Integer): String;
|
|
begin
|
|
case nAction of
|
|
1 : Result := 'Create';
|
|
3 : Result := 'Modify';
|
|
5 : Result := 'Rename';
|
|
else Result := Format('Unknown-%d', [nAction]);
|
|
end;
|
|
end;
|
|
|
|
procedure process_KVC_RESPONSE_KEYWORD_SEARCH;
|
|
var
|
|
sPath, sText, sFounds,
|
|
sClass, sFormat, sHeader, sResult: String;
|
|
nTotalHits: Integer;
|
|
DocInfo: TAdDocInfo;
|
|
PO: TPrefModel;
|
|
begin
|
|
// _Trace('Found Path="%s"', [aRcv.S['Path']]);
|
|
PO := gMgSvc.ModePolicy;
|
|
|
|
sPath := aRcv.S['Path'];
|
|
sText := aRcv.S['Text'];
|
|
if gMgSvc.IsNewApi then
|
|
sFounds := gMgSvc.MgRule.GetRuleNamesFromIds(aRcv.S['Founds'])
|
|
else
|
|
sFounds := aRcv.S['Founds'];
|
|
nTotalHits := aRcv.I['TotalHits'];
|
|
if aRcv.O['Info'] <> nil then
|
|
DocInfo := TTgJson.GetDataAsType<TAdDocInfo>(aRcv.O['Info'])
|
|
else
|
|
ZeroMemory(@DocInfo, SizeOf(DocInfo));
|
|
|
|
if (DocInfo.eClass > -1) and (DocInfo.eClass < 22) then
|
|
sClass := ENdocClassDescStrs[DocInfo.eClass]
|
|
else
|
|
sClass := 'Unknown format';
|
|
if (DocInfo.eFormat > -1) and (DocInfo.eFormat < 437) then
|
|
sFormat := ENdocFmtDescStrs[DocInfo.eFormat]
|
|
else
|
|
sFormat := 'No Format Found';
|
|
sHeader := Format(DOC_HEADER_FMT, [sClass, sFormat]);
|
|
|
|
// sResult := Format('<eCrmPath>%s</eCrmPath>%s<eCrmBody>%s</eCrmBody>' +
|
|
// '<Found>%s</Found><Hits>%d</Hits>', [sPath, sHeader, sText, sFounds, nTotalHits]);
|
|
sResult := Format('<eCrmPath>[%s] %s</eCrmPath>%s<eCrmBody>%s</eCrmBody>' +
|
|
'<Found>%s</Found><Hits>%d</Hits>',
|
|
[GetEventToStr(aRcv.I['Event']), sPath, sHeader, sText, sFounds, nTotalHits]);
|
|
|
|
case aRcv.I['Action'] of
|
|
FILEMON_WRITEMON :
|
|
begin
|
|
// case nType of
|
|
// TYPE_MSG_PREVENT_FILECHANGE : sHeader := LOGCODE_PREVENT_FILEMONITOR;
|
|
// TYPE_MSG_PREVENT_FILEMASK : sHeader := LOGCODE_PREVENT_FILEMASK;
|
|
// TYPE_MSG_PREVENT_FILEWRITE : sHeader := LOGCODE_PREVENT_FILEIO;
|
|
// TYPE_MSG_PREVENT_FILEDRMENC : sHeader := PREVENT_DRM_ENCRYPT;
|
|
// end;
|
|
|
|
if PO.IsOldPolicy then
|
|
begin
|
|
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEMONITOR, sResult);
|
|
if PO.IsOldPolicy or Po.FileMon.IsNoti then
|
|
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, Format('%s|%s|%d', [sPath, sFounds, nTotalHits]));
|
|
end else begin
|
|
var LogInfo: TLogInfo;
|
|
ZeroMemory(@LogInfo, SizeOf(LogInfo));
|
|
LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR;
|
|
|
|
if (aRcv.S['SchName'] <> '') and
|
|
(aRcv.S['FoundSum'] <> '') then
|
|
begin
|
|
var OA: ISuperObject := TSuperObject.Create(stArray);
|
|
var OTemp: ISuperObject;
|
|
var StrList: TStringList;
|
|
var RstList: TStringList;
|
|
var i: Integer;
|
|
Guard(StrList, TStringList.Create);
|
|
SplitString(aRcv.S['SchName'], RESULT_SEPARATOR, StrList);
|
|
Guard(RstList, TStringList.Create);
|
|
SplitString(aRcv.S['FoundSum'], RESULT_SEPARATOR, RstList);
|
|
for i := 0 to StrList.Count - 1 do
|
|
begin
|
|
OTemp := SO;
|
|
OTemp.S['RULE_ID'] := StrList[i];
|
|
OTemp.S['TEXT'] := RemoveOverlapWords(RstList[i], ';');
|
|
OTemp.S['CNT'] := IntToStr(GetCountOverlapWordsCount(GetCountOverlapWords(RstList[i], ';')));
|
|
OA.AsArray.Add(OTemp);
|
|
end;
|
|
|
|
LogInfo.OVio := OA;
|
|
end;
|
|
|
|
if PO.FileMon.IsCollectTxt then
|
|
LogInfo.sBody := sText;
|
|
if PO.FileMon.IsCollectFile then
|
|
begin
|
|
if GetFileSize_path(sPath) <= (LONGLONG(Po.FileMonLimitMB) * 1048576) then
|
|
begin
|
|
LogInfo.sFileCompId := gMgSvc.MakeComponentId(sPath);
|
|
if Po.FileMon.DoEnc then
|
|
begin
|
|
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
|
|
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileMonMinMB, Po.FileMonLimitMB, crtAIP)
|
|
else
|
|
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileMonMinMB, Po.FileMonLimitMB, crtDRM);
|
|
end else
|
|
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileMonMinMB, Po.FileMonLimitMB);
|
|
end;
|
|
end else
|
|
if Po.FileMon.DoEnc then
|
|
begin
|
|
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
|
|
gMgSvc.ThdReact.AddEnt(crtAIP, sPath, Po.FileMonEncDelaySec)
|
|
else if not NotUseDRM or UseFasooEncrypt then
|
|
gMgSvc.ThdReact.AddEnt(crtDRM, sPath, Po.FileMonEncDelaySec);
|
|
end;
|
|
|
|
LogInfo.sPath := sPath;
|
|
// Action : 1 = Add, 2 = Delete, 3 = Modify, 4 = Rename, 5 = NewName
|
|
case aRcv.I['Event'] of
|
|
5 : LogInfo.sSummary := Format('[Rename] %s', [sPath + ' < Old : ' + aRcv.S['OldName']]);
|
|
else LogInfo.sSummary := Format('[%s] %s', [GetEventToStr(aRcv.I['Event']), sPath]);
|
|
end;
|
|
|
|
if aRcv.B['MakeDrm'] then
|
|
LogInfo.sResInfo := 'DRM';
|
|
|
|
gMgSvc.SendEventLogEx(@LogInfo, false);
|
|
|
|
if PO.FileMon.IsNoti then
|
|
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, Format('%s|%s|%d', [LogInfo.sSummary, sFounds, nTotalHits]));
|
|
end;
|
|
end;
|
|
FILEMON_WRITEBLOCK :
|
|
begin
|
|
if PO.IsOldPolicy then
|
|
begin
|
|
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEIO, sResult);
|
|
if PO.IsOldPolicy or Po.FileBlock.IsNoti then
|
|
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, Format('%s|%s|%d', [sPath, sFounds, nTotalHits]));
|
|
ThdDelFiles_.Push(sPath);
|
|
end else begin
|
|
var LogInfo: TLogInfo;
|
|
ZeroMemory(@LogInfo, SizeOf(LogInfo));
|
|
LogInfo.sCode := LOGCODE_PREVENT_FILEIO;
|
|
|
|
if (aRcv.S['SchName'] <> '') and
|
|
(aRcv.S['FoundSum'] <> '') then
|
|
begin
|
|
var OA: ISuperObject := TSuperObject.Create(stArray);
|
|
var OTemp: ISuperObject;
|
|
var StrList: TStringList;
|
|
var RstList: TStringList;
|
|
var i: Integer;
|
|
Guard(StrList, TStringList.Create);
|
|
SplitString(aRcv.S['SchName'], RESULT_SEPARATOR, StrList);
|
|
Guard(RstList, TStringList.Create);
|
|
SplitString(aRcv.S['FoundSum'], RESULT_SEPARATOR, RstList);
|
|
for i := 0 to StrList.Count - 1 do
|
|
begin
|
|
OTemp := SO;
|
|
OTemp.S['RULE_ID'] := StrList[i];
|
|
OTemp.S['TEXT'] := RemoveOverlapWords(RstList[i], ';');
|
|
OTemp.S['CNT'] := IntToStr(GetCountOverlapWordsCount(GetCountOverlapWords(RstList[i], ';')));
|
|
OA.AsArray.Add(OTemp);
|
|
end;
|
|
|
|
LogInfo.OVio := OA;
|
|
end;
|
|
|
|
if PO.FileBlock.IsCollectTxt then
|
|
LogInfo.sBody := sText;
|
|
if PO.FileBlock.IsCollectFile then
|
|
begin
|
|
if GetFileSize_path(sPath) <= (LONGLONG(PO.FileBlkLimitMB) * 1048576) then
|
|
begin
|
|
LogInfo.sFileCompId := gMgSvc.MakeComponentId(sPath);
|
|
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileBlkMinMB, PO.FileBlkLimitMB, crtDelete);
|
|
end;
|
|
end else
|
|
ThdDelFiles_.Push(sPath);
|
|
LogInfo.sPath := sPath;
|
|
LogInfo.sSummary := Format('[Create] %s', [sPath]);
|
|
|
|
gMgSvc.SendEventLogEx(@LogInfo);
|
|
|
|
if PO.FileBlock.IsNoti then
|
|
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, Format('%s|%s|%d', [LogInfo.sSummary, sFounds, nTotalHits]));
|
|
end;
|
|
end;
|
|
FILEMON_DRM :
|
|
begin
|
|
if gMgSvc.IsNewApi then
|
|
begin
|
|
var LogInfo: TLogInfo;
|
|
ZeroMemory(@LogInfo, SizeOf(LogInfo));
|
|
LogInfo.sCode := PREVENT_DRM_ENCRYPT;
|
|
LogInfo.sPath := sPath;
|
|
LogInfo.sSummary := '[DRM] ' + ExtractFileName(sPath);
|
|
gMgSvc.SendEventLogEx(@LogInfo, false);
|
|
end else
|
|
gMgSvc.SendEventLog(URI_USER_ACTION, PREVENT_DRM_ENCRYPT, sResult);
|
|
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEDRMENC, Format('%s|%s|%d', [sPath, sFounds, nTotalHits]));
|
|
ThdEncFiles_.Push(sPath);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
try
|
|
case aRcv.Command of
|
|
KVC_RESPONSE_KEYWORD_SEARCH : process_KVC_RESPONSE_KEYWORD_SEARCH;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. ProcessRcvPacket()');
|
|
end;
|
|
end;
|
|
|
|
end.
|