BSOne.SFC/eCrmHE/EXE_eCrmHomeEdition/Manager/ManagerService.pas

14266 lines
459 KiB
Plaintext

{*******************************************************}
{ }
{ ManagerService }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit ManagerService;
interface
uses
Tocsg.Obj, System.SysUtils, System.Classes, HandleConfig,
ThdEvent, System.SyncObjs, ManagerModel, NicService,
Winapi.Windows, Winapi.Messages, System.Generics.Collections,
Tocsg.Thread, IdHTTP, IdSSLOpenSSL, IdIOHandler, FileService,
VulnerabilityService, Tocsg.USB, ThdFirewall, ThdInstMon, ThdWebUrl,
Tocsg.MSAA, Winapi.oleacc, ManagerPattern, Tocsg.Printer,
ThdMtpMon, Tocsg.Bluetooth, CttSchDefine, ThdSchFileScan, Tocsg.Clipboard,
ThdUsbMon, ManagerHook, ThdSendFiles, ThdWinUpdateScan, ThdRouteMon,
Tocsg.Process, HandleSecurity, AppCtrlDefine, Tocsg.WndUtil,
ManagerCampaign, ManagerRule, superobject, Define, ThdReaction,
Vcl.Graphics, DSchPiNoti, Tocsg.Win32, Tocsg.Fasoo, UserAuthentification, RecoverService,
ThdPrintWork, xPrintLogService, ManagerPrint, ThdScreenRecord, ProcessRecentDoc, Bs1FltCtrl, DeviceGuard.Logic;
{$I Define.inc}
const
JSON_PI_TEST = 'PersonalInfo.json';
WM_POPUP_MSG = WM_USER + 3938;
WM_POPUP_LICENSE = WM_POPUP_MSG + 1;
WM_POPUP_MSG_SYSTEM = WM_POPUP_MSG + 2;
WM_POPUP_AFTERREPORT = WM_POPUP_MSG + 3;
WM_REFRESH_VIEW = WM_USER + 3951;
WM_SCREENLOCK = WM_REFRESH_VIEW + 1;
WM_REFRESH_CLIPBOARDCHAIN = WM_SCREENLOCK + 1;
WM_REQ_AGENT_UNINSTALL = WM_REFRESH_CLIPBOARDCHAIN + 1;
WM_REQ_FILETAG_CONTROL = WM_REQ_AGENT_UNINSTALL + 1;
WM_REQ_KWDSCH_CONTROL = WM_REQ_FILETAG_CONTROL + 1;
WM_UPDATE_SCREENLOGO = WM_REQ_KWDSCH_CONTROL + 1;
WM_REQ_OUTLOOK_CONTROL = WM_UPDATE_SCREENLOGO + 1;
WM_POPUP_PRINTWATER_PROGRESS = WM_REQ_OUTLOOK_CONTROL + 1;
WM_POPUP_MSG2 = WM_POPUP_PRINTWATER_PROGRESS + 1;
WM_POPUP_MSG_PI = WM_POPUP_MSG2 + 1;
type
TCheckAgentInfo = packed record
sAgentId,
sIp, sIps, sMAC,
sAccount,
sHostName, // sStatusType,
sEulaCon, sLocation, sPwSet, sPwSetTermOk,
sScrnLock, sOsVer, sAvInfo,
// sAsInfo,
sFwInfo, sOsSafe, sPatchExist,
sAvSafe, sFwSafe,
sAvUptodate,
sPiSafe, // sSafeBlock,
sModeName,
sEmpNo: String;
// bSafePcSHCD: Boolean; // 나중에 삭제 예정 23_0313 16:19:12 kku // 제거 24_0521 13:26:33 kku
bJoinAD: Boolean; // AD 이행 여부 확인 for HEC, GEC 24_0521 13:27:02 kku
end;
TExpFun = record
bUsb,
bMtp,
bBT,
bWifi,
bCB: Boolean;
nUseMin: Integer;
end;
PFileExpEnt = ^TFileExpEnt;
TFileExpEnt = record
sPath,
sHash: String;
dtReg: TDateTime;
end;
TFileExpEntList = TList<PFileExpEnt>;
PRecentFnd = ^TRecentFnd;
TRecentFnd = record
dtReg: TDateTime;
curAppType: TCurAppType;
sMName,
sPath,
sFounds,
sFoundsC: String;
bResult: Boolean;
end;
TRecentFndList = TList<PRecentFnd>;
PDpEnt = ^TDpEnt;
TDpEnt = record
dwTick,
dwDSec: DWORD;
sId: String;
end;
TDelayProcList = TList<PDpEnt>;
TBS1ModeKind = (hmkSleep, hmkSecurity, hmkVulnerability, hmkOffline, hmkException);
TManagerService = class(TTgObject)
private
CS_,
CSDev_: TCriticalSection;
// Force 설정
nForceLogLv_: Integer;
bFirstAip_: Boolean; // DEV 버전에서 AIP 우선 적용할지 25_0909 14:52:52 kku
HTTP_: TIdHTTP;
SSL_: TIdSSLIOHandlerSocketOpenSSL;
BS1ModeKind_: TBS1ModeKind;
hRcvHwnd_: HWND;
IgrEjectDrives_,
ServerUrlList_,
ActiveConnectList_: TStringList;
nDestSvrIdx_: Integer;
dwUNameChkTick_: DWORD;
wURole_: WORD; // 사용자 역할, 0 : none, 1 : 결재자, 2 : 위임자
sUName_, // 현재 KOCES에서만 사용한다. 사용하려면 TimerProcessStatus()에서 업체 추가해야함 23_0328 07:44:45 kku, 2.7 신규서버 이상에서 사용
sEmail_, // 2.7
sDeptName_, // 2.7 신규서버 이상에서 사용
sEmpNo_,
sAgentId_,
sDestIPort_,
sDestSvrUrl_,
sVpnClient_,
sExtraPort_,
sAutoRunBlockKey_,
sRecentPrintDocName_, // 가장 최근에 워터마크 또는 보안적용된 출력 문서 이름 23_0329 10:18:54 kku
sNetworkPreventValue_,
sNetworkExceptValue_,
sNetworkPreventType_: String;
bDoCbUpdate_,
bIsEmpNoOk_,
bDoEmpNoCheck_,
bIsRouterOn_,
bIsVpnNicOn_,
bIsConnected_,
bIsUninstall_,
bIsTemporaryConn_, // 보안모드 임시 연결
// bIsNexgVpnRegistered_,
bIsNetworkPrevent_: Boolean;
dtCreateMg_,
dtConnected_,
dtChangeMode_: TDateTime;
dwCheckSafePC_, // 신한카드 safePC 체크, 나중에 삭제해야함 23_0109 14:56:17 kku
dwTempConnBegin_: DWORD;
sEulaContent_, // 사용 동의서 내용 가지고 있게 22_0503 10:01:13 kku
sNoticeContent_: String; // 한번 보여준 공지사항을 갖고 있는다, 업데이트 되면 비교해서 다시 보여주기 위함 22_0503 10:20:20 kku
sModeName_,
sDomain_,
sComName_,
sAccount_,
sUserName_: String;
bIsSafeExitImpossible_,
bIsVpnClientON_,
bIsRestricMac_: Boolean;
bTryUnsafeActionsMin_,
bIsPatchUptoDate_, // HandlePatch.isPatch
bIsServiceAvailable_: Boolean;
PrefModel_,
PrefIdlModel_,
PrefVulModel_,
PrefOffline_,
PrefExpPolicy_: TPrefModel;
AgentModel_: TAgentModel;
dtOldLogCheck_,
dtSoftInstTick_,
dtInfoFileCheck_: TDateTime; // 소프트웨어 설치 수집 체크 시간
MgCttSch_: TManagerCttSch;
MgCttSchExp_: TManagerCttSchExcept;
// MgCltFld_: TManagerCltFld;
HandleConfig_: THandleConfig;
HandleSecurity_: THandleSecurity;
NicService_: TNicService;
VulService_: TVulnerabilityService;
ThdOsUpdateScan_: TThdWinUpdateScan;
ThdEvent_: TThdEvent;
ThdFW_: TThdFirewall;
FileService_: TFileService;
UsbNoti_: TTgUSBEventNotify;
ThdInstMon_: TThdInstMon;
ThdWebUrl_: TThdWebUrl;
ThdBlueMon_: TThdBtDevNotify;
ThdMtpMon_: TThdMtpMon;
ThdPrinter_: TTgPrtSpoolWatch;
ThdPrintWork_: TThdPrintWork;
ThdUsbMonRO_: TThdUsbMon;
EmDriveList_: TStringList;
ThdRouteMon_: TThdRouteMon;
ThdCapAppMon_,
ThdBlockAppMon_: TThdProcessWatch;
ThdCltFld_: TThdSendFilesFromDir;
ThdScreenRecord_: TThdScreenRecord;
MgHook_: TManagerHook;
CapAppList_,
MonAppList_,
BlockAppList_,
BlockAppWList_: TStringList;
bIsMonApp_,
bIsBlockApp_: Boolean;
sMonApps_,
sBlockApps_: String;
ThdScanSch_: TThdSchFileScan;
MgFnd_: TManagerFound;
bTerminateThdScanSch_: Boolean;
sSchRstPath_,
sSchRstExpPath_: String;
ThdTaskTimer_,
ThdDevTaskTimer_, // 장치 차단이 오래 걸리는 경우가 있어서 별도 스레드 추가 25_1113 11:05:53 kku
ThdStatusTimer_: TThdTaskTimer;
sRecentUserSid_,
sAgentPatchVersion_: String;
dwSecuExitWaitTick_: DWORD; // 보안모드 해제 대기 23_1107 16:00:30 kku
// 유프리즘 화상 회의 감지를 위함 22_0621 15:20:31 kku
AccObj_SubTitle_: IAccessible;
varSubTitle_: OleVariant;
hEditWnd_: HWND;
MgCampn_: TManagerCampaign; // 캠패인 관리
MgRule_: TManagerRule; // 룰 관리
bSchRstVul_, // 개인정보 임계치
bRcvRemoveAgent_, // 삭제 명령 받음
bPreNacChk_: Boolean; // 최근 NAC 연결 체크
dwSLSaveTick_, // SL 저장 간격
dwNacChkTick_: DWORD; // NAC 체크 간격
MgPtn_: TManagerPattern;
PatternEntList_: TPatternEntList;
// 상태전송, 정책 수신 주기
dwStatusInterval_: DWORD;
// 컨텐츠 필터를 위함
sCbPatterns_,
sPrintPatterns_,
sWebABPatterns_,
sEtcABPatterns_,
sOutABPatterns_: String;
CbPatternEnts_: TPatternEntList;
BtcontentsFilter_list_,
UsbcontentsFilter_list_,
CdromcontentsFilter_list_,
MtpcontentsFilter_list_,
UsbToUsbcontentsFilter_list_: string;
agentStatTime_: string;
// RDP 로그인된 상태 체크 23_0926 08:58:58 kku
bIsRdpLogon_: Boolean;
// Shell context menu DRM
mtxDrmEnc_,
mtxDrmDec_,
mtxPrtWater_: TTgMutex;
// DRM 열람 권한
// mtxDrmOpen_: TTgMutex;
// 백신 정보확인 주기 설정을 위함 (신한카드)
// dtLastAvCheck_: TDateTime;
// 상시로고, 화면 캡쳐 앱 제어 발동 APP
sScreenLogoChkApps_,
sScreenLogoChkUrls_,
sScreenBlockChkApps_: String;
ScreenLogoChkAppList,
ScreenLogoChkUrlList,
ScreenBlockChkAppList: TStringList;
bForceScreenLogo_,
bForceScreenCapAppBlock_: Boolean;
nMonitorCnt_: Integer;
sScreenLogoData_: String;
wScreenVI_: WORD;
// 문서 열람 관리
DcOpenDoc_: TDictionary<DWORD,String>;
// 오프라인 정책
bIsOffline_: Boolean;
dtApDisconn_,
dtSvrDisconn_: TDateTime;
// 예외 정책
bIsExpPolicy_: Boolean;
nExpPoMin_: Integer;
llChkTimeSec_: LONGLONG;
dtExpPoBegin_: TDateTime;
// 아웃룩 정책
// bInitOutMail_,
bBlockOutlook_: Boolean;
ThdWndMon_: TThdActiveWndMon;
ThdAppMon_: TThdProcessWatch;
// 프린트 워터마크
qWaterEnts_: TQueue<PPrtWaterEnt>;
// tifHelp1_,
// tifHelp2_: TWICImage;
MgPwe_: TManagerPrtWaterExcept; // 프린트 워터마크 예외
sRecentLabel_: String; // GEC에서 최근 레이블값 사용 24_0513 15:53:58 kku
// USB 최근 연결 USB
sExceptUsbDev_,
sExceptUsbDevKn_,
sRecentUsbDrv_: String;
UsbConnList_: TStringList; // 연결된 USB드라이브 목록
DriveList_: TStringList;
// CD/DVD 예외 처리 정보
sCdException_,
sCdExcepedList_,
sFailCdBlock_: String;
// API New, Old 구분 23_0801 14:40:13 kku
bIsNewApi_,
bCheckedFixDisk_: Boolean;
sLastPolicy_: String;
dtLastChangePW_,
dtLastLogOn_: TDateTime;
UseOptCodeList_: TStringList;
// HttpPost() 오류
nHttpError_: Integer;
sHttpError_: String;
// 작업중인 캠패인
pProcCampn_: PCampnEnt;
bClearCampn_, // 테스트를 위해 추가
bIsStopCampn_, // 캠페인 중지 됐나
bIgrLastWorkCampn_: Boolean; // 증분검사 테스트를 위함
llCampnEncCnt_,
llCampnEncFailCnt_: LONGLONG; // 작업 스레드가 끝난 후에도 진행, 결과값을 알기 위해 백업 23_1214 16:31:27 kku
DlgEncCampn_: TDlgSchPiNoti;
NoMatchList_: TStringList;
ThdReact_: TThdReaction; // 대응 스레드
dtLastChk_: TDateTime; // 시간 변경 체크
// 스크린 로고 진하게
bIsAppUseScreenLogo_, // 프로그램 사용 시 상시로고 진하게 추가 24_1016 19:19:46 kku
bIsScreenLogoBold_,
bIsIdleScreenLogo_,
bIsIpMatchScreenLogo_,
bIsRdpLogonScreenLogo_: Boolean;
// 윈도우 7버전인가
bWin7Ver_: Boolean;
// 프린트 마스킹...
sPrtMaskingStr_: String;
// RDP 해상도 체크, 조정
nRdpW_, nRdpH_: Integer;
// 서브원 파일 생성 차단 알림은 최대 1분에 한번만 뜨게해야함 24_0718 10:57:03 kku
dtSV1FileBlockNoti_: TDateTime;
// AIP 모듈 실행 3번 실패 시 10분 다시 시도하도록 기능 추가
dwAipExeTick_: DWORD;
// 출력 대기
MgPrint_: TManagerPrint;
// UTC 시간 계산 (한국=+09:00)
sUtcOffset_: String;
// WM_ENDSESSION 처리
bIsEndSession_: Boolean;
// 파일 반출
FileExpEntList_: TFileExpEntList;
// 프린트 워터마크 1회 예외
bPrtWaterExcept_: Boolean;
// 컨텐츠 필터를 통해 브라우저, 아웃룩, 프로세스 파일 차단 시 검출정보 25_0325 08:48:59 kku
RecentFndList_: TRecentFndList;
// 컨텐츠 룰 준비
bInitRule_: Boolean;
// 파수 DRM 복호화를 위해 사용
fas_: TTgFasoo;
// HW 정보 전송
bIsSendHWInfo_: Boolean;
// xPrint 로그 처리
xPrintLogService_: TxPrintLogService;
xPrintVer_: String;
// 서버 연결 상태 체크
nChkConnSec_: Integer;
dwTickChkConn_: DWORD;
// 일정시간 이후 처리를 위한 체크 확인용
DelayProcList_: TDelayProcList;
// 문서 파일 열람 확인 (임시, for LG디스플레이) 25_1106
RecentDocWatch_: TRecentDocWatch;
// 필터 드라이버를 통한 장치제어
FltCtrl_: TBs1fltControl;
bFltCtrlInit_ : Boolean;
FltCtrlPolicy_: DWORD;
DcFltCtrlEnt_: TDictionary<String,String>;
DeviceGuard_: TDeviceGuardEngine;
sEjectWbDrive_: String;
hEjectWbDrive_: THandle;
bIgrPrtPause_: Boolean;
bIsManualSecurityMode_: Boolean; // 로그인 성공시 보안모드 진입 플
procedure Lock;
procedure Unlock;
procedure DevLock;
procedure DevUnlock;
procedure UpdateEmptyUsbInfo;
procedure CatchDriveSatate;
function GetConnected: Boolean;
function GetTemporaryConn: Boolean;
procedure DoEjectCDROM;
procedure DoEjectUsbDrive(sDrive: String; nType: Integer = -1);
procedure DoEjectUsbDrives;
procedure CheckHostAndUserInfo;
procedure ProcessCampaign;
procedure ProcessStatusOld(bFailChangeDestUrl: Boolean = true);
procedure TimerCheckOsConfig(aSender: TObject); //
// procedure TimerCheckConnect(aSender: TObject);
procedure TimerCheckServiceAvailable(aSender: TObject); //
procedure TimerCheckTemporaryConn(aSender: TObject); // <<
procedure TimerCheckConnect(aSender: TObject); // <<
procedure TimerProcessStatus(aSender: TObject); // <<
procedure TimerCheckSecurity(aSender: TObject); //
procedure TimerCheckExpPo(aSender: TObject); // <<
procedure TimerProcessDevTask(aSender: TObject); // <<
function GetModePolicy: TPrefModel;
procedure DeactivePolicyAll;
function IsRunProcess(sChkProc: String; var sOldProc: String; OldProcList: TStringList; var bDetectProc: String): Boolean;
function IsUseProcess(sChkProc: String; var sOldProc: String; OldProcList: TStringList; var bDetectProc: String): Boolean;
function IsUseUrl(sChkUrl: String; var sOldUrl: String; OldUrlList: TStringList; var bDetectUrl: String): Boolean;
procedure UpdatePolicyActive(aPrefModel: TPrefModel);
procedure SetSchRstVul(bVal: Boolean);
procedure LoadSchRstVul;
function GetIsRestricDate: Boolean;
procedure ProcessReleaseQuarantineFiles;
function GetLastPolicy: String;
procedure SetLastPolicy(sLP: String);
procedure UpdateIgrUsbSerial4FltCtr(sData: String ; FltCtrlPolicy : DWORD);
procedure UpdateFltCtrlEnts(sDrive, sDevInfo: String);
function GetFltCrltEntInfo(sDrive: String): String;
procedure ProcessUSBArrival(sDrive: String);
procedure OnUSBArrival(Sender: TObject; pInfo: PDevBroadcastVolume);
procedure OnUSBQueryRemove(Sender: TObject; sDrive: String; var bAccept: Boolean);
procedure ProcessUSBRemove(sDrive: String);
procedure OnUSBRemove(Sender: TObject; pInfo: PDevBroadcastVolume);
function ProcessPreventBT(pEnt: PBtDevEnt; var bExcept: Boolean): Boolean;
procedure OnBtDevEntNotify(pEnt: PBtDevEnt; csBT: TBTChangeStates; var bPrevent: Boolean);
procedure OnPtrJobNotify(Sender: TThdPrtSpoolWatch; Job: TPrtJobInfo);
procedure OnCapAppNotify(aSender: TThdProcessWatch; pEnt: PPwEnt; aKind: TProcessWatchKind);
procedure OnBlockAppNotify(aSender: TThdProcessWatch; pEnt: PPwEnt; aKind: TProcessWatchKind);
procedure OnWndNotify(aSender: TObject; hActiveWnd: HWND);
procedure OnAppNotify(aSender: TThdProcessWatch; pEnt: PPwEnt; aKind: TProcessWatchKind);
procedure OnWaterEntNotify(Sender: TObject; const Item: PPrtWaterEnt; Action: TCollectionNotification);
procedure OnFileExpNotify(Sender: TObject; const Item: PFileExpEnt; Action: TCollectionNotification);
procedure OnRecentFndNotify(Sender: TObject; const Item: PRecentFnd; Action: TCollectionNotification);
procedure OnDpEntNotify(Sender: TObject; const Item: PDpEnt; Action: TCollectionNotification);
// function FindAipMdWnd(bForceUp: Boolean = false): HWND;
function IsUsbDrvConn: Boolean;
// 티맵 사번 체크 보정 23_1212 18:39:24 kku
procedure CheckEmpNo_TMAP;
function GetModeKind: TBS1ModeKind;
procedure SetModeKind(aKind: TBS1ModeKind);
procedure SetModeName(sModeName: String);
function GetModeName: String;
procedure SendStartAgentAuditLog;
public
RecoverSvc_: TRecoverService;
AgentInfo: TCheckAgentInfo;
UpdateTick: DWORD;
// AIP
AipFailCnt: Integer; // 모듈 실행/연동 실패 카운트 24_0704 08:51:53 kku
UseApproval: Boolean;
// xPrint Data Update Datetime
dtOneDay_: TDateTime; // 하루 한번만 업데이트 체크, 임시 25_0924 14:56:30 kku
EmpsUpDt,
PrtsUpDt,
BillUpDt,
MkcdUpDt,
LumpUpDt: String;
sTmpAcc_: String;
// 테스트 기능
SharePcPrintBlock,
WSDPortPrintBlock,
TcpIpPrintBlock,
PrintSavingBlock: Boolean;
Constructor Create(hRcvHwnd: HWND);
Destructor Destroy; override;
function RecentUserSid: String;
procedure ChangeDestinationUrl;
procedure DoClipboardUpdate;
procedure StopService;
procedure SetConnected(bVal: Boolean; bNewApi: Boolean);
function HttpPost(sDest, sRqType, sParam: String; pnRespCode: PInteger = nil): String;
function MakeComponentId(sTail: String): String;
function GetCbFoundContentToJsonObj(sText: String; var sResultStr: String): ISuperObject;
procedure UpdateInternalInfo;
procedure OgnRecentFndList;
function GetRecentFnd(sPath: String; var aEnt: TRecentFnd): Boolean;
procedure AddDelayProcEnt(sId: String; dwDSec: DWORD);
function HasDelayProcEntById(sId: String): Boolean;
procedure AddRecentFnd(aEnt: TRecentFnd);
procedure DelRecentFnd(sPath: String);
procedure SetPatternList(sPatternOpt: String; var aList: TPatternEntList);
procedure SetRuleToPtrnList(sRuleIds: String; var aList: TPatternEntList; bUseRName: Boolean = false);
function GetAipUPN: String;
function FindAipMdWnd(bForceUp: Boolean = false): HWND;
// 문서 열람 관리 (LGD)
function AddOpenDoc(dwPid: DWORD; sPath: String): Boolean;
procedure DelOpenDocProc(dwPid: DWORD);
function SendPrintImgFiles(sImgPath, sImgOutDir: String; nCollectMax: Integer = 0; aRespaction: TCampnRespaction = crtNone): String;
function SendPrintEmfFiles(sEmfDir, sImgOutDir: String; nCollectMax: Integer = 0; aRespaction: TCampnRespaction = crtNone): String;
procedure SetRouterOn(bVal: Boolean);
procedure SetVpnNicOn(bVal: Boolean);
procedure SetPatchUpdate(bIsUptoDate: Boolean);
procedure SetServiceAvailable(bVal: Boolean);
procedure SetTemporaryConn(bVal: Boolean);
// procedure SetNexgVpnRegistered(bVal: Boolean);
procedure SetNetworkPrevent(bVal: Boolean);
procedure SetNetworkPreventVal(sVal: String);
procedure SetNetworkExceptVal(sVal: String);
procedure SetNetworkPreventType(sVal: String);
procedure SetExtraPort(sVal: String);
procedure SetRecentPrintDocName(sVal: String);
procedure AddPrtHookJob(aO: ISuperObject);
procedure UpdateAgentInfo;
procedure SendEventLog(sUri, sCode, sMsg: String; bPrevent: Boolean = true);
procedure SendEventLogEx(pInfo: PLogInfo; bPrevent: Boolean = true; dtLog: TDateTime = 0); overload;
procedure SendEventLogEx(sCode, sSummary: String; bPrevent: Boolean = true; dtLog: TDateTime = 0); overload;
procedure SendRequest(sCode: String; aExptInfo: TReqDevExceptInfo; sComment, sBeginDate, sDueDate: String; nTarget: Integer; sMsg: String); // target : 0 - 해당 pc, 1 - 해당 사용자, 2 - 해당 부서, 3-전체
procedure SendFile(var LogInfo: TLogInfo; sApi, sPath: String; nMinMB: Integer = 0; nLimitMB: Integer = 50; aRespaction: TCampnRespaction = crtNone; nRespDelaySec: Integer = 0);
procedure SendFileNor(bSendBin: Boolean; sCompId, sApi, sPath: String; nMinMB: Integer = 0; nLimitMB: Integer = 50; aRespaction: TCampnRespaction = crtNone; nRespDelaySec: Integer = 0);
procedure SendCttSchProgInfo(aProg: TCttSchProg);
procedure SendCampnProgInfo(aProg: TCttSchProg);
procedure SendCttSchDetailInfo(sTaskId: String; pResult: PSchResult; nProcType: Integer);
procedure SendAppInstInfo;
function SendHwInfo: Boolean;
procedure SendScreenRecord(sReason, sMp4Path: String; nMilSec: Integer);
//mgkim
procedure SendIntegrityAuditLog(const JsonReport: string);
function SendApproval(nType: Integer; pData: Pointer; bUpFileCnt: Integer = 0): String;
procedure SendAgreeInfo;
function GetApprovalUrl(sReqType: String): String;
function GetRegPerInfoUrl: String;
function GetPostData(sUrl, sData: String; sReqType: String = ''): String;
function DirectSendEventLog(sUri, sCode, sMsg: String; bPrevent: Boolean = false): Boolean;
procedure PopupMessage(nType: Integer; sData: String = '');
procedure PopupSystemMsg(nType: Integer);
procedure PopupLicensed;
procedure PopupAfterReport;
procedure RefreshView;
procedure UpdateScreenLogo(bForce: Boolean = false);
procedure DoCheckOsUpdate;
procedure ProcessVpnConnect;
procedure ProcessVpnDisconnect;
function IsOfflineMode: Boolean;
procedure OnUnzipProgress(Sender : TObject; Progress : Byte; var Abort : Boolean);
procedure OnPwdEvent(Sender : TObject; var NewPassword : String);
function HasContentInfo(sMName, sPath: String; aAppType: TCurAppType): Boolean;
function IsSearchingPersonalInfo: Boolean;
// 구 개인정보 검사
procedure StartPiSchTask(aOpt: TFileScanOpt; dtScan: TDateTime; bSendEvent: Boolean = true);
procedure StopPiSchTask;
procedure OnPiSchTaskBegin(aSender: TObject);
procedure OnPiSchTaskEnd(aSender: TObject);
procedure ProcessPiSchFound(pResult: PSchResult);
// 캠패인 검사
procedure StartCampaignTask(pCamEnt: PCampnEnt);
procedure StopCampaignTask;
procedure OnCampaignTaskBegin(aSender: TObject);
procedure OnCampaignTaskEnd(aSender: TObject);
procedure ProcessCampnFound(pResult: PSchResult);
procedure UpdateCttSchVulState(bForce: Boolean = false);
function ProcessMergeCampaignBkData(OInfo: ISuperObject): Integer;
procedure AddFileExpEnt(sPath, sHash: String);
procedure SaveFileExpEnt;
procedure LoadFileExpEnt;
procedure OrganizeFileExpEnt;
function HasFileExp(sPath: String): Boolean;
procedure DoPrint(pEnt: PPrtEnt);
function IsScreenLogo: Boolean;
procedure SetExpPolicyActive(aFun: TExpFun);
procedure ClearExpPolicy;
procedure AddPrintWaterEnt(pWEnt: PPrtWaterEnt);
procedure ProcessPrintWaterEnt;
procedure ResetPersonalScan;
procedure RetryPersonalScan;
// function IsHecDev: Boolean; // HEC 개발계인가?
function GetAipPath: String;
function GetUrlBlockList: String;
procedure AddEncIgr(sPath: String);
procedure AddAfterEnc(sPath: String);
function HasEncIgr(sPath: String; bChkDel: Boolean = false): Boolean;
procedure ProcessEndSession;
// [yhkim] 로그인 시 수동모드 -> 보안모드
procedure ChangeLoginMode(Sender: TObject; ResultCode: Integer);
property RcvHwnd: HWND read hRcvHwnd_;
property DestServerUrl: String read sDestSvrUrl_;
property Connected: Boolean read GetConnected;
property VpnClient: String read sVpnClient_;
property IsRouterOn: Boolean read bIsRouterOn_;
property IsVpnNicOn: Boolean read bIsVpnNicOn_;
property IsUninstall: Boolean read bIsUninstall_;
property IsTemporaryConn: Boolean read GetTemporaryConn;
property IsVpnClientON: Boolean read bIsVpnClientON_ write bIsVpnClientON_;
property IsSafeExitImpossible: Boolean read bIsSafeExitImpossible_ write bIsSafeExitImpossible_;
property IsRestricMac: Boolean read bIsRestricMac_;
property IsRestricDate: Boolean read GetIsRestricDate;
property TempConnBegin: DWORD read dwTempConnBegin_;
// property IsNexgVpnRegistered: Boolean read bIsNexgVpnRegistered_;
property ActiveConnectList: TStringList read ActiveConnectList_;
// property RouterDefList: TRouterList read RouterDefList_;
property ExtraPort: String read sExtraPort_;
property IsEmpNoOk: Boolean read bIsEmpNoOk_ write bIsEmpNoOk_; // [사검]
property UName: String read sUName_ write sUName_;
property Email: String read sEmail_;
property DeptName: String read sDeptName_ write sDeptName_;
property EmpNo: String read sEmpNo_;
property Domain: String read sDomain_;
property UserName: String read sUserName_;
property ComName: String read sComName_;
property Account: String read sAccount_;
property AgentId: String read sAgentId_;
// property ActiveThdreadProcess: Boolean write SetActiveThdreadProcess;
property IsServiceAvailable: Boolean read bIsServiceAvailable_;
property IsPatchUptoDate: Boolean read bIsPatchUptoDate_;
property EulaContent: String read sEulaContent_;
property HandleConfig: THandleConfig read HandleConfig_;
property HandleSecurity: THandleSecurity read HandleSecurity_;
property NicService: TNicService read NicService_;
property VulService: TVulnerabilityService read VulService_;
property AgentModel: TAgentModel read AgentModel_;
property PrefModel: TPrefModel read PrefModel_;
property SleepPolicy: TPrefModel read PrefIdlModel_;
property VulPolicy: TPrefModel read PrefVulModel_;
property ModePolicy: TPrefModel read GetModePolicy;
property HeModeKind: TBS1ModeKind read GetModeKind;
property ThdScanSch: TThdSchFileScan read ThdScanSch_;
property ThdWebUrl: TThdWebUrl read ThdWebUrl_;
property ThdPrintWork: TThdPrintWork read ThdPrintWork_;
property ThdOsUpdateScan: TThdWinUpdateScan read ThdOsUpdateScan_;
property IsSchRstVul: Boolean read bSchRstVul_ write SetSchRstVul;
property MgHook: TManagerHook read MgHook_;
property ChangeModeDT: TDateTime read dtChangeMode_ write dtChangeMode_;
property ServerUrlList: TStringList read ServerUrlList_;
property MgCttSch: TManagerCttSch read MgCttSch_;
property MgCttSchExp: TManagerCttSchExcept read MgCttSchExp_;
property MgPwe: TManagerPrtWaterExcept read MgPwe_;
property MgPrt: TManagerPrint read MgPrint_;
property DoEmpNoCheck: Boolean read bDoEmpNoCheck_ write bDoEmpNoCheck_;
// property ApDisconnDT: TDateTime read dtApDisconn_ write dtApDisconn_;
property LastChangePwDT: TDateTime read dtLastChangePW_;
// property IsOffline: Boolean read bIsOffline_ write bIsOffline_;
property IsOfflineExp: Boolean read bIsExpPolicy_;
property OffPolicy: TPrefModel read PrefOffline_;
property ExpPolicy: TPrefModel read PrefExpPolicy_;
property ExpPolicyBeginDT: TDateTime read dtExpPoBegin_;
property ExpPolicyUseMin: Integer read nExpPoMin_;
property UseOptCodeList: TStringList read UseOptCodeList_;
property DestIPort: String read sDestIPort_;
property HTTP: TIdHTTP read HTTP_;
// property LastPolicy: String read sLastPolicy_ write sLastPolicy_;
property LastPolicy: String read GetLastPolicy write SetLastPolicy;
property HttpErrorCode: Integer read nHttpError_;
property HttpErrorMsg: String read sHttpError_;
property EventLog: TThdEvent read ThdEvent_;
property IsScreenLogoBold: Boolean read bIsScreenLogoBold_;
property IsIpMatchScreenLogo: Boolean read bIsIpMatchScreenLogo_ write bIsIpMatchScreenLogo_;
property IsWin7Ver: Boolean read bWin7Ver_;
property IsStopCampn: Boolean read bIsStopCampn_;
property CampnEnc: LONGLONG read llCampnEncCnt_;
property CampnEncFail: LONGLONG read llCampnEncFailCnt_;
property DlgEncCampn: TDlgSchPiNoti read DlgEncCampn_ write DlgEncCampn_;
property RcvRemoveAgent: Boolean read bRcvRemoveAgent_ write bRcvRemoveAgent_;
property UserRole: WORD read wURole_ write wURole_;
property IsPrtWaterExcept: Boolean read bPrtWaterExcept_ write bPrtWaterExcept_;
property PrtMaskingStr: String read sPrtMaskingStr_ write sPrtMaskingStr_;
property PrintPatterns: String read sPrintPatterns_;
property RecentLabel: String read sRecentLabel_ write sRecentLabel_;
property RecentPrintDocName: String read sRecentPrintDocName_;
property xPrintVer: String read xPrintVer_ write xPrintVer_;
property ThdxPrintLog: TxPrintLogService read xPrintLogService_;
property ForceLogLv: Integer read nForceLogLv_;
property FirstAip: Boolean read bFirstAip_;
property IsNewApi: Boolean read bIsNewApi_;
property MgCampn: TManagerCampaign read MgCampn_;
property MgRule: TManagerRule read MgRule_;
property MgPrint: TManagerPrint read MgPrint_;
property ProcCampn: PCampnEnt read pProcCampn_;
property ThdReact: TThdReaction read ThdReact_;
property IsRdpLogon: Boolean read bIsRdpLogon_;
property FileService: TFileService read FileService_;
property ModeName: String read GetModeName;
property UtcOffset: String read sUtcOffset_;
end;
function ExtrTextFromFile(sPath: String; bIgrImg: Boolean = false): String;
function GetDefAipLabelId(bEncCamp: Boolean = false): String;
function ExtrTextFromPrintImgFiles(sImgPath: String; aAngle: Extended = 0): String;
function ExtrTextFromPrintEmfFiles(sEmfDir: String; aAngle: Extended = 0): String;
procedure SetPrtJobFromHelperApp(aJob: TPrtJobInfo; dwCmd: DWORD);
function EmfToPng(const sEmfPath, sPngPath: string;
nDPI: Integer = 96; aBackColor: TColor = clWhite): Boolean;
function GetFileToSha1Str_BS1(sPath: String): String;
var
gMgSvc: TManagerService = nil;
resourcestring
RS_SleepMode = '수면모드';
RS_HEC_SleepMode = '사외모드';
RS_SecuMode = '보안모드';
RS_HEC_SecuMode = '사내모드';
RS_VulMode = '취약모드';
RS_OfflineMode = '오프라인';
RS_UnverifiedMode = '미인증';
RS_OfflineExpMode = '예외사용';
RS_MsgChangeMode = '"%s" 로 변경 되었습니다.';
RS_MsgChangeMode2 = '"%s" 모드로 변경 되었습니다.';
RS_WatchNetState = '네트워크 연결상태를 확인해주세요.';
implementation
uses
//GlobalSLCore, SearchLightClient,
Tocsg.Safe, Tocsg.Strings, Condition, CrmLogger, CrmUtil, Tocsg.Convert,
Tocsg.Exception, License, Tocsg.WTS, IdGlobal,
IdTCPClient, Tocsg.Disk, Tocsg.Driver,
Tocsg.Path, GlobalDefine, Tocsg.WscApi,
System.DateUtils, System.Zip, Tocsg.Files, Tocsg.WinInfo, Tocsg.DateTime,
Tocsg.Registry, Tocsg.Trace, Winapi.ActiveX, Tocsg.Network, Winapi.WinSpool,
EM.jwabluetoothapis, Tocsg.PCRE, Tocsg.AppInfo, System.Variants,
Tocsg.Json, Tocsg.Shell, ManagerPerInfo, Tocsg.Encrypt, Tocsg.DRM.Encrypt,
ParserLinkFile, IdMultipartFormData, Tocsg.Packet,
System.IniFiles, IdExceptionCore, SecureApp, BsKwdSchKvCttSchClient,
GlobalOutAddInDefine, OutlookMonClient, IdException, Tocsg.Url, ThdExecuteEndNoti,
SynPdf, Vcl.Printers, Vcl.Imaging.pngimage, aes_type, Tocsg.Hex,
aes_cbc, ProcessServerAPI, System.Hash, imageen, hyieutils, ManagerFixedDisk,
Tocsg.Delete, Tocsg.Graphic, Winapi.GDIPAPI, Vcl.Imaging.jpeg, ManagerImgMskData,
Vcl.Forms, STLabGuardModule, System.Win.Registry, System.Generics.Defaults,
Tocsg.Kess, DefineHelper, System.TimeSpan, ProcessSoftcampDRM, Tocsg.Hash,
Tocsg.Fasoo.Global, ProcessDecompress, Tocsg.WMI, System.IOUtils, Tocsg.Valid,
EM.PdfiumCore, System.Math, Tocsg.Service, Winapi.WinSvc, ThdRcvPolicy, Tocsg.AIP, IdStack, ThdInitProc, ProcessPrint, ProcessPrintWater, Tocsg.FileInfo, System.Masks;
var
// _bmpWaterP: TBitmap = nil;
_bmpST: TBitmap = nil;
backupCdromBlockKind: TUsbBlockKind;
//const
// JSON_CONNCHECK = '{"Request : ConnectionCheck"}';
var
_CheckVpnProcs: String = '';
_CheckVpnList: TStringList = nil;
function GetDefAipLabelId(bEncCamp: Boolean = false): String;
begin
case CUSTOMER_TYPE of
CUSTOMER_DEV :
begin
if bEncCamp then
Result := 'a86ece2e-0ab0-4e24-8aca-c410c0ecab59' // 대외비
else
Result := '946ee615-f74c-4312-ac00-17ccc40d3504'; // 대외비 개인정보
end;
CUSTOMER_GEC,
CUSTOMER_HDENG :
begin
if bEncCamp then
Result := 'cdcaf456-5176-400c-b0e6-6301b2c47597' // 대외비
else
Result := '9877e059-3e04-4eba-ad87-888eb0c7e9ba'; // 대외비 개인정보
end;
// CUSTOMER_HAE : Opt.CttSchOpt.sAipLabelId := 'a5b98469-3cf3-4f5e-ad43-b098cf00ed03';
// CUSTOMER_JUVIS : Result := '2e3dfd6a-d02d-4d3a-9b4e-7566f8653478'; // 대외비
CUSTOMER_HCA : Result := 'c4742a8b-ba73-461d-b4fd-1adcac5fcdde'; // 평문
CUSTOMER_KDNVN : Result := 'e7bd3a2c-b905-4bdb-8892-e6cd8d1eb00b'; // 대외비
CUSTOMER_UNITUS : Result := 'afd3f50f-3ef1-4996-bd1b-16799f799fe2'; // 개인정보(Privacy) 25_0325 09:39:25 kku, '486b827d-7fb1-48c7-a363-db75665f1ecd'; // Secret
CUSTOMER_MOTRAS : Result := '49459909-2e25-4650-b7cf-dfff204b8977'; // 개인정보(Privacy) 25_0416 10:07:22 kku, 'dca5269d-a66f-4bbb-9ee0-593c30687184'; // 대외비 (Employee Only)
CUSTOMER_SKEC : Result := 'b460538c-150a-470c-8f77-8a530e2f607f';// 사내 한 //' b31df88e-5819-4d7e-8cd4-caebd9b5e897'; // 보호문서
CUSTOMER_CJONS : Result := 'a7082a6c-0558-48a5-a82a-128def7f07c5'; // 그룹한
CUSTOMER_WHANIN : Result := 'f7514e58-6d0e-452b-bd2a-dde9e2bd3b93'; // Internal > Whanin
else Result := '';
end;
end;
procedure InstallOutlookPlugIn_forHD(h: HWND); inline;
var
sDir,
sHlpExe: String;
begin
try
sDir := GetRunExePathDir + DIR_CONF;
sHlpExe := sDir + EXE_HLP;
if FileExists(sHlpExe) then
begin
var O: ISuperObject := SO;
O.I['RcvWnd'] := h;
O.B['RunAs'] := true;
O.I['Cmd'] := HPCMD_INSTALL_OUTLOOK_ADDIN;
O.S['MdDir'] := sDir;
SaveJsonObjToFile(O, sDir + DAT_PARAM);
if FileExists(sDir + DAT_PARAM) then
begin
{$IFDEF DEBUG}
ExecutePath(sHlpExe);
TTgTrace.T('Outlook 플러그인 설치 시도..', 3);
{$ELSE}
ExecuteAppAsUser('explorer.exe', sHlpExe, '', SW_SHOWNORMAL);
ExecuteAppAsUser('msedge.exe', sHlpExe, '', SW_SHOWNORMAL);
TTgTrace.T('Outlook 플러그인 설치 시도...', 3);
{$ENDIF}
end else
TTgTrace.T('Error .. Outlook 플러그인 설치 파라메터 오류..', 3);
if FileExists(sDir + 'PATCH.exe') then
begin
TTgTrace.T('Outlook 플러그인 설치 PATCH..', 3);
ExecuteAppAsUser('explorer.exe', sDir + 'PATCH.exe', '', SW_SHOWNORMAL);
ExecuteAppAsUser('msedge.exe', sDir + 'PATCH.exe', '', SW_SHOWNORMAL);
end;
end else
TTgTrace.T('[InstOutPlug] Helper 프로세스를 찾을 수 없습니다.', 1);
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. InstallOutlookPlugIn_forHD()');
end;
end;
function ExtractLogValue(const Source, Key: string): string;
var
P, PEnd: Integer;
begin
Result := '';
P := Pos(Key, Source);
if P > 0 then
begin
Inc(P, Length(Key));
PEnd := P;
while (PEnd <= Length(Source)) and (Source[PEnd] <> ',') do
Inc(PEnd);
Result := Trim(Copy(Source, P, PEnd - P));
end;
end;
procedure ProcessUsbLogString(const sRecvMsg: string);
var
sVid, sPid: string;
sFriendlyName, sBlkSerial, sDrive, sType, sClassGuid: string;
llSize: Int64;
nPos : Int32;
begin
if Pos('DISABLE(1)', sRecvMsg) = 0 then
Exit;
sDrive:= 'USB:';
llSize:= 0;
// 예: sRecvMsg = '... Vid: 0x346D, Pid : 0x5678, Serial : 8328501217610604362'
sVid := ExtractLogValue(sRecvMsg, 'Vid:');
sPid := ExtractLogValue(sRecvMsg, 'Pid :'); // 원본 문자열의 공백 주의
sBlkSerial := ExtractLogValue(sRecvMsg, 'Serial :');
// Vid와 Pid를 조합하여 장치 식별 이름(FriendlyName) 생성
sVid := StringReplace(sVid, '0x', '', [rfReplaceAll, rfIgnoreCase]);
sPid := StringReplace(sPid, '0x', '', [rfReplaceAll, rfIgnoreCase]);
sFriendlyName := Format('USB_VID_%s&PID_%s', [sVid, sPid]);
if gMgSvc.ModePolicy.USBPopup then
begin
var sRegSerial: String := sBlkSerial;
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_USBDISCONN, sDrive + '*9*' +
ByteSizeToStr(llSize) + '*9*' + sFriendlyName + '*9*' + sType + '*9*' + sRegSerial);
end;
var sMsg: String := Format('USB Blocked : Name=%s, Drive=%s (%s), Type=%s, Serial=%s',
[sFriendlyName, sDrive, ByteSizeToStr(llSize), sType, sBlkSerial]);
if gMgSvc.bIsNewApi_ then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_PREVENT_USB;
LogInfo.sDevName := sFriendlyName;
LogInfo.sDevSerial := sBlkSerial;
LogInfo.sDevClassId := sClassGuid;
LogInfo.sSummary := sMsg;
gMgSvc.SendEventLogEx(@LogInfo);
end
else
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_USB, sMsg);
end;
function FltCtrlCallback(sContext: Pointer): DWORD; stdcall;
var
sLog: String;
nPos: Integer;
O: ISuperObject;
begin
if sContext = nil then
exit;
sLog := String(PChar(sContext));
TThread.Queue(nil,
procedure
begin
{$IFDEF DEBUG}
gMgSvc._Trace(sLog, 1);
{$ELSE}
gMgSvc._Trace('[MGKIM] %s', [sLog], 5);
{$ENDIF}
nPos := Pos('{', sLog);
if nPos > 0 then
begin
Delete(sLog, 1, nPos - 1);
O := SO(sLog);
if O.S['name'] <> '' then
gMgSvc.UpdateFltCtrlEnts(O.S['name'] + '\', Trim(O.S['vid']) + '§' + Trim(O.S['pid']) + '§' + Trim(O.S['serial']));
end
else
begin
ProcessUsbLogString(sLog)
end
end);
Result := 0;
end;
{ TManagerService }
procedure TManagerService.ChangeLoginMode(Sender: TObject; ResultCode: Integer);
begin
if ResultCode = CODE_AUTH_OK then
begin
begin
// 서비스 가용 상태를 True로 변경 (GetModePolicy가 보안모드를 선택하도록 함)
bIsManualSecurityMode_ := True; // 수동 인증 성공
bIsServiceAvailable_ := True; // 서비스 가용 상태로 강제 전환
// GetModePolicy 로직 참조: 보안 모드 진입 시 필요한 설정 강제 적용
try
// 레지스트리 caller 값을 3으로 (보안모드 의미)
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\eCrmHomeEdition', 'caller', 3, true);
// 보안 모드 시작 로그 전송
if Assigned(gMgSvc) then
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_SECURITY_START, 'Security Mode');
_Trace('인증 성공으로 인한 수동 모드 변경 : 수면모드 > 보안모드', 1);
// 정책 엔진 다시 호출 (화면 로고 업데이트 및 팝업 처리를 위해)
GetModePolicy;
// 화면 로고 즉시 업데이트
if IsScreenLogo then
UpdateScreenLogo(true);
except
on E: Exception do
_Trace('ChangeLoginMode Error: ' + E.Message);
end;
end;
end;
end;
Constructor TManagerService.Create(hRcvHwnd: HWND);
procedure InitHttp;
begin
try
SSL_ := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SSL_.SSLOptions.Method := sslvSSLv23;
SSL_.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
HTTP_ := TIdHTTP.Create(nil);
HTTP_.IOHandler := SSL_;
with HTTP_ do
begin
// HandleRedirects := true;
// Request.BasicAuthentication := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/json; charset=utf-8'; //'application/xml';
Request.Accept := 'application/json; charset=utf-8';
Request.Charset := 'utf-8';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
Request.Connection := 'close';
HTTPOptions := HTTPOptions - [hoKeepOrigProtocol];
case CUSTOMER_TYPE of
CUSTOMER_DEMO :
begin
ConnectTimeout := 3000;
ReadTimeout := 10000;
end;
CUSTOMER_KFTC :
begin
ConnectTimeout := 3000;
ReadTimeout := 30000;
end;
CUSTOMER_KR :
begin
ConnectTimeout := 10000;
ReadTimeout := 60000;
end;
CUSTOMER_SHCD :
begin
// 신한카드 타임아웃 180초 23_0327 14:18:03 kku // 다시 30, 60초로 변경 23_0410 08:28:17 kku
ConnectTimeout := 30000;
ReadTimeout := 60000;
end;
else begin
ConnectTimeout := 5000;
ReadTimeout := 30000;
end;
end;
end;
except
end;
{$IFDEF DEBUG}
var O: ISuperObject;
var sRes := GetEmpNoInfo(DestServerUrl, HTTP_, sEmpNo_);
if sRes = '' then
exit;
try
O := SO(sRes);
except
exit;
end;
if (O.S['result'] = 'false') or (O.S['deleteyn'] <> 'false') then
begin
// 에이전트 사번 정보가 없거나 삭제 상태라면 설치 로그를 보내준다 23_0403 09:43:04 kku
// SendEventLog(URI_CONNECT, SYSEVT_AGENT_INSTALL, '[TEST] Agent first connected');
// 서버에서 마지막 모드 로그로 현재 에이전트 모드를 판별하게 되는데 최초 정보가 없으면 에이전트 목록에 보이지 않게 된다. 23_0403 13:22:43 kku
SendEventLog(URI_USER_ACTION, MODE_SECURITY_END, '[DEBUG..REG] Sleep mode');
end;
{$ENDIF}
end;
procedure ExecuteLogin;
var
LoginForm: TAuthForm;
begin
LoginForm := TAuthForm.Create(nil);
LoginForm.OnSuccess := ChangeLoginMode; // 성공했을때 호출할 함수 등록
LoginForm.sAgentId := sAgentId_;
LoginForm.sDestIPort := sDestIPort_;
LoginForm.Show;
end;
procedure InitAgentInfo;
var
sPath: String;
ss: TStringStream;
StrList: TStringList;
begin
UpdateAgentInfo;
if (sEmpNo_ = '') or (sAgentId_ = '') then
begin
_Trace('InitAgentInfo() .. Not found AgentInfo ..');
if IsAccountEmpNo then
exit;
// todo : 앞으로 eCrmManager 업데이트 후 에이전트 정보와 정책을 받아와야 한다. 22_0502 16:23:28 kku
{$IFDEF DEBUG}
sEmpNo_ := 'kjkim';
{$ELSE}
sEmpNo_ := 'Empty'; // GetRandomString(8);
{$ENDIF}
sPath := GetProgramFilesDir + DIR_HE + DIR_CONF + PROP_USERINFO;
if FileExists(sPath) then
begin
Guard(ss, TStringStream.Create('', TEncoding.UTF8));
ss.LoadFromFile(sPath);
Guard(StrList, TStringList.Create);
if SplitString(DecryptStr(ss.DataString), '---', StrList) > 1 then
begin
sEmpNo_ := StrList[0];
// sVpnId_ := StrList[1];
end;
end;
sAgentId_ := GetAgentId(sEmpNo_);
with AgentModel_ do
begin
if NicService_ <> nil then
begin
IP := NicService_.GetIP;
MAC := NicService_.GetMAC;
end else begin
IP := '1.2.3.4';
MAC := 'aaaaaaaa';
end;
if IsUseHostNameOnly then
HostName := sComName_
else if VulService_ <> nil then
HostName := VulService_.WindowsAccount
else
HostName := 'hostname';
LastConn := Now;
Version := SdkVersion;
AgentId := sAgentId_;
EulaDT := 0;
Location := 'Unknown';
// VpnInfo := sVpnId_;
_Trace('[05] 사번 변경, %s > %s', [EmpNo, sEmpNo_]);
// SendEventLogEx(LOG_CHANGE_EMPNO, Format('[Init] EmpId Changed. (%s > %s)', [EmpNo, sEmpNo_]), false);
EmpNo := sEmpNo_;
end;
// AgentModel_.Save; 아래에서 함 22_0721 15:24:12 kku
end;
//[yhkim]
ExecuteLogin();
if CUSTOMER_TYPE = CUSTOMER_LOTTEMART then
begin
// 실행마다 NAC에서 유저 ID값 가져오기
sPath := GetRegValueAsString(HKEY_LOCAL_MACHINE,
'SOFTWARE\Geni\Genian\Common', 'Auth');
if sPath.Length > 2 then
begin
// MT는 롯데마트, SP는 롯데슈퍼
if sPath.ToUpper.StartsWith('MT') or
sPath.ToUpper.StartsWith('SP') then Delete(sPath, 1, 2);
if AgentModel_.EmpNo <> sPath then
begin
_Trace('[04] 사번 변경, %s > %s', [AgentModel_.EmpNo, sPath]);
SendEventLogEx(LOG_CHANGE_EMPNO, Format('[LT_Init] EmpId Changed. (%s > %s)', [AgentModel_.EmpNo, sPath]), false);
AgentModel_.EmpNo := sPath;
AgentModel_.Save;
end;
end;
end;
end;
procedure InitDefCttPattern;
const
TAG_INFOS = '주민등록번호|전화번호|차량번호|이메일주소';
var
StrList: TStringList;
PtrnEnt: TPatternEnt;
i: Integer;
begin
MgPtn_ := TManagerPattern.Create;
MgPtn_.LangId := $0412;
PatternEntList_ := TPatternEntList.Create(false);
Guard(StrList, TStringList.Create);
SplitString(TAG_INFOS, '|', StrList);
for i := 0 to StrList.Count - 1 do
begin
PtrnEnt := MgPtn_.GetPatternEntByName(StrList[i]);
PatternEntList_.Add(PtrnEnt);
end;
MgPtn_.LangId := 1; // 컨텐츠 필터 사용을 위함
end;
procedure LoadSetting;
var
ini: TIniFile;
sTemp: String;
begin
Guard(ini, TiniFile.Create(GetProgramFilesDir + DIR_TG + INI_FORCEHE));
nForceLogLv_ := ini.ReadInteger('Force', 'LogLv', 0);
if nForceLogLv_ > 0 then
begin
gTrace.Level := nForceLogLv_;
gTrace.LevelLock := true;
end;
if CUSTOMER_TYPE = CUSTOMER_DEV then
bFirstAip_ := ini.ReadBool('Force', '1AIP', false);
// dtLastAvCheck_ := ini.ReadDateTime('Customer', 'LastAvCheck', 0);
sTemp := RecentUserSid + '\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced';
if CUSTOMER_TYPE = CUSTOMER_KIMCHANG then
begin
SetRegValueInteger(HKEY_USERS, sTemp, 'DisablePreviewDesktop', 0, true);
SetRegValueInteger(HKEY_USERS, sTemp, 'DisablePreviewWindow', 0, true);
end else begin
if GetRegValueAsInteger(HKEY_USERS, sTemp, 'ExtendedUIHoverTime') <> $10000 then
begin
SetRegValueInteger(HKEY_USERS, sTemp, 'ExtendedUIHoverTime', $10000, true);
_Trace('작업표시줄 미리보기 OFF 설정 1', 1);
end;
// 작업표시줄 포커스 기능 해제. 상시로고가 무력화 되는것을 방지 25_0618 15:16:13 kku
SetRegValueInteger(HKEY_USERS, sTemp, 'DisablePreviewDesktop', 1, true);
SetRegValueInteger(HKEY_USERS, sTemp, 'DisablePreviewWindow', 1, true);
end;
end;
begin
Inherited Create;
ASSERT(gMgSvc = nil);
// CoInitialize(nil); // 프린트 워터마크 파일 분석을 위해 FindPrintingFile() 서 사용 24_0513 16:02:49 kku
SetRegValueInteger(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'CT', CUSTOMER_TYPE, true);
SetRegValueString(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'RW', IntToStr(hRcvHwnd), true);
sTmpAcc_ := '';
FormatSettings.ShortDateFormat := 'YYYY-MM-DD';
FormatSettings.LongDateFormat := 'YYYY-MM-DD';
FormatSettings.ShortTimeFormat := 'hh:mm:ss';
FormatSettings.LongTimeFormat := 'hh:mm:ss';
FormatSettings.DateSeparator := '-';
FormatSettings.TimeSeparator := ':';
dtCreateMg_ := Now;
PDFiumDllDir := GetRunExePathDir;
UpdateTick := 0;
sPrtMaskingStr_ := '';
sRecentUserSid_ := '';
sAgentPatchVersion_ := '';
gMgSvc := Self;
CS_ := TCriticalSection.Create;
CSDev_ := TCriticalSection.Create;
hRcvHwnd_ := hRcvHwnd;
IgrEjectDrives_ := TStringList.Create;
IgrEjectDrives_.CaseSensitive := false;
ServerUrlList_ := TStringList.Create;
GetDestServerList(ServerUrlList_);
ASSERT(ServerUrlList_.Count > 0);
ActiveConnectList_ := TStringList.Create;
dtConnected_ := 0;
dtChangeMode_ := Now;
nDestSvrIdx_ := 99999; // ChangeDestinationUrl() 사용 시 초기화를 위함
bIsEmpNoOk_ := false; //(CUSTOMER_TYPE = CUSTOMER_CJOV_GLOBAL); // false;
bDoEmpNoCheck_ := false;
bIsConnected_ := false;
bIsRouterOn_ := false;
bIsVpnNicOn_ := false;
sVpnClient_ := GetVpnClient;
bIsUninstall_ := false;
bIsTemporaryConn_ := false;
// bIsNexgVpnRegistered_ := true;
bIsNetworkPrevent_ := false;
sNetworkPreventValue_ := '';
sNetworkExceptValue_ := '';
sNetworkPreventType_ := '';
sAutoRunBlockKey_ := '';
dtLastChk_ := 0;
sUName_ := '';
sEmail_ := '';
dwUNameChkTick_ := 0;
sExtraPort_ := '';
sEulaContent_ := '';
dwCheckSafePC_ := 0;
dwTempConnBegin_ := 0;
bIsVpnClientON_ := false;
bIsSafeExitImpossible_ := false;
bIsRestricMac_ := false;
BS1ModeKind_ := hmkSleep;
dtSoftInstTick_ := 0;
dtOldLogCheck_ := 0;
bTryUnsafeActionsMin_ := false;
dtInfoFileCheck_ := Now;
sSchRstPath_ := '';
sSchRstExpPath_ := '';
ZeroMemory(@AgentInfo, SizeOf(AgentInfo));
sLastPolicy_ := '';
sRecentPrintDocName_ := '';
// dtLastAvCheck_ := 0;
dtLastChangePW_ := 0;
dtLastLogOn_ := JavaToDelphiDateTime(StrToInt64Def(GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'LLO'), 0));
bIsOffline_ := false;
bIsExpPolicy_ := false;
dtApDisconn_ := 0;
dtSvrDisconn_ := Now;
dtExpPoBegin_ := 0;
nExpPoMin_ := 0;
llChkTimeSec_ := 0;
qWaterEnts_ := TQueue<PPrtWaterEnt>.Create;
sRecentUsbDrv_ := '';
sExceptUsbDev_ := '';
sExceptUsbDevKn_ := '';
UsbConnList_ := TStringList.Create;
UsbConnList_.CaseSensitive := false;
DriveList_ := TStringList.Create;
DriveList_.CaseSensitive := false;
sCdException_ := '';
sCdExcepedList_ := '';
sFailCdBlock_ := '';
bCheckedFixDisk_ := false;
nHttpError_ := 0;
sHttpError_ := '';
pProcCampn_ := nil;
bIsStopCampn_ := false;
llCampnEncCnt_ := 0;
llCampnEncFailCnt_ := 0;
DlgEncCampn_ := nil;
bClearCampn_ := false;
bIgrLastWorkCampn_ := false;
bIsIdleScreenLogo_ := false;
bIsIpMatchScreenLogo_ := false;
bIsRdpLogonScreenLogo_ := false;
bIsAppUseScreenLogo_ := false;
bIsScreenLogoBold_ := false;
dwSecuExitWaitTick_ := 0;
sModeName_ := RS_SleepMode;
nRdpW_ := 0;
nRdpH_ := 0;
AipFailCnt := 0;
dwAipExeTick_ := 0;
dtSV1FileBlockNoti_ := 0;
wURole_ := 0;
UseApproval := false;
bIgrPrtPause_ := false;
bIsEndSession_ := false;
FileExpEntList_ := TFileExpEntList.Create;
FileExpEntList_.OnNotify := OnFileExpNotify;
LoadFileExpEnt;
sRecentLabel_ := '';
sScreenLogoChkApps_ := '';
sScreenLogoChkUrls_ := '';
sScreenBlockChkApps_ := '';
bForceScreenLogo_ := false;
nMonitorCnt_ := 0;
sScreenLogoData_ := '';
wScreenVI_ := 0;
case CUSTOMER_TYPE of
CUSTOMER_DEV,
CUSTOMER_DEMO,
CUSTOMER_LGD : DcOpenDoc_ := TDictionary<DWORD,String>.Create;
else DcOpenDoc_ := nil;
end;
bForceScreenCapAppBlock_ := false;
ScreenLogoChkAppList := TStringList.Create;
ScreenLogoChkAppList.CaseSensitive := false;
ScreenLogoChkUrlList := TStringList.Create;
ScreenLogoChkUrlList.CaseSensitive := false;
ScreenBlockChkAppList := TStringList.Create;
ScreenBlockChkAppList.CaseSensitive := false;
NoMatchList_ := TStringList.Create;
NoMatchList_.CaseSensitive := false;
MgPrint_ := TManagerPrint.Create;
UseOptCodeList_ := TStringList.Create;
RecentFndList_ := TRecentFndList.Create;
RecentFndList_.OnNotify := OnRecentFndNotify;
DelayProcList_ := TDelayProcList.Create;
DelayProcList_.OnNotify := OnDpEntNotify;
bInitRule_ := false;
bIsSendHWInfo_ := false;
nChkConnSec_ := 10;
dwTickChkConn_ := 0;
// bInitOutMail_ := false;
bBlockOutlook_ := false;
ThdWndMon_ := nil;
ThdAppMon_ := nil;
xPrintLogService_ := nil;
sUtcOffset_ := '+00:00';
try
var TS: TTimeSpan := TTimeZone.Local.GetUtcOffset(Now);
sUtcOffset_ := Format('%s%.2d:%.2d', [BooleanToStr(TS.Ticks >= 0, '+', '-'), Abs(TS.Hours), Abs(TS.Minutes)]);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetUtcOffset()');
end;
// DRM, AIP 아이콘 오버레이 추가 24_0227 08:52:01 kku
if IsUsingIconOverlay then
begin
var sShellDll: String;
if IsSupportAIP then
begin
sShellDll := GetRunExePathDir + DIR_CONF + DLL_OVI_AIP;
if not ExistsKey(HKEY_LOCAL_MACHINE, REG_BS1_OVI_AIP) and FileExists(sShellDll) then
ExecutePath_hide('regsvr32.exe', '/s /i "' + sShellDll + '"');
end;
if not NotUseDRM then
begin
sShellDll := GetRunExePathDir + DIR_CONF + DLL_OVI_DRM;
if not ExistsKey(HKEY_LOCAL_MACHINE, REG_BS1_OVI_DRM) and FileExists(sShellDll) then
ExecutePath_hide('regsvr32.exe', '/s /i "' + sShellDll + '"');
end;
end else begin
var sDir: String := GetRunExePathDir + DIR_CONF;
if ExistsKey(HKEY_LOCAL_MACHINE, REG_BS1_OVI_DRM) and FileExists(sDir + DLL_OVI_DRM) then
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sDir + DLL_OVI_DRM]));
if ExistsKey(HKEY_LOCAL_MACHINE, REG_BS1_OVI_AIP) and FileExists(sDir + DLL_OVI_AIP) then
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sDir + DLL_OVI_AIP]));
end;
// if IsExplorerDrmMenu or (CUSTOMER_TYPE = CUSTOMER_HAE) then
if IsExplorerDrmMenu then
begin
var sShellDll: String := GetRunExePathDir + DIR_CONF + DLL_SHELL;
if not ExistsKey(HKEY_CLASSES_ROOT, REG_BS1_SHELL) and FileExists(sShellDll) then
ExecutePath_hide('regsvr32.exe', '/s /i "' + sShellDll + '"');
if CUSTOMER_TYPE = CUSTOMER_SKEC then
mtxDrmEnc_ := TTgMutex.Create(MUTEX_SHELL_MIPENC)
else if not NotUseDRM then
mtxDrmEnc_ := TTgMutex.Create(MUTEX_SHELL_DRMENC);
end else
mtxDrmEnc_ := nil;
mtxDrmDec_ := nil;
mtxPrtWater_ := nil;
// mtxDrmOpen_ := nil;
AccObj_SubTitle_ := nil;
VariantClear(varSubTitle_);
hEditWnd_ := 0;
AgentModel_ := TAgentModel.Create;
AgentModel_.Load;
MgCttSch_ := TManagerCttSch.Create;
MgCttSchExp_ := TManagerCttSchExcept.Create;
MgPwe_ := TManagerPrtWaterExcept.Create;
// MgPwe_.AddFileHash('C:\Users\kku\Desktop\BSOne_OutTest.docx');
// MgCltFld_ := TManagerCltFld.Create;
sComName_ := GetComName;
PrefModel_ := TPrefModel.Create('01');
// 수면 모드
PrefIdlModel_ := TPrefModel.Create('02', true, false); // 기본 로드 하도록 변경 23_0907 11:34:45 kku
if PrefModel_.IdlPolicy <> '' then
PrefIdlModel_.SetPrefModel(SO(PrefModel_.IdlPolicy));
// 취약 모드
PrefVulModel_ := TPrefModel.Create('03', true, false);
if PrefModel_.VulPolicy <> '' then
PrefVulModel_.SetPrefModel(SO(PrefModel_.VulPolicy));
// 오프라인 모드
PrefOffline_ := TPrefModel.Create('04', true, false);
if PrefModel_.OffPolicy <> '' then
PrefOffline_.SetPrefModel(SO(PrefModel_.OffPolicy));
// 예외 모드
PrefExpPolicy_ := TPrefModel.Create('05', true, false);
// if PrefModel_.ExpPolicy <> '' then
// PrefExpPolicy_.SetPrefModel(SO(PrefModel_.ExpPolicy));
MgCampn_ := TManagerCampaign.Create;
MgRule_ := TManagerRule.Create;
bIsNewApi_ := not PrefModel_.IsOldPolicy;
if PrefModel_.VpnAppName <> '' then
sVpnClient_ := PrefModel_.VpnAppName;
sNoticeContent_ := PrefModel_.NoticeContent;
bFirstAip_ := false;
LoadSetting;
bIsPatchUptoDate_ := true;
// bIsPatchUptoDate_ := false; // OS 패치 취약 테스트
bIsServiceAvailable_ := false;
HandleConfig_ := THandleConfig.Create;
HandleSecurity_ := THandleSecurity.Create(HandleConfig_.OsVersion);
NicService_ := TNicService.Create;
VulService_ := TVulnerabilityService.Create;
UsbNoti_ := TTgUSBEventNotify.Create;
UsbNoti_.OnUSBArrival := OnUSBArrival;
UsbNoti_.OnUSBQueryRemove := OnUSBQueryRemove;
UsbNoti_.OnUSBRemove := OnUSBRemove;
ThdFW_ := TThdFirewall.Create;
ThdFW_.StartThread;
ThdReact_ := TThdReaction.Create;
ThdReact_.StartThread;
ThdEvent_ := TThdEvent.Create;
ThdEvent_.StartThread;
sCbPatterns_ := '';
CbPatternEnts_ := TPatternEntList.Create;
sPrintPatterns_ := '';
sWebABPatterns_ := '';
sEtcABPatterns_ := '';
sOutABPatterns_ := '';
InitDefCttPattern;
RecentDocWatch_ := nil;
ThdOsUpdateScan_ := nil;
FileService_ := nil;
ThdInstMon_ := nil; // TThdInstMon.Create(hRcvHwnd);
ThdWebUrl_ := nil; // TThdWebUrl.Create;
ThdPrinter_ := nil;
ThdPrintWork_ := nil;
ThdBlueMon_ := nil;
ThdMtpMon_ := nil;
ThdUsbMonRO_ := nil;
EmDriveList_ := TStringList.Create;
EmDriveList_.CaseSensitive := false;
UpdateEmptyUsbInfo;
ThdRouteMon_ := nil;
ThdCapAppMon_ := nil;
ThdBlockAppMon_ := nil;
ThdScanSch_ := nil;
ThdCltFld_ := nil;
ThdScreenRecord_ := nil;
MgFnd_ := nil;
MgHook_ := nil;
bTerminateThdScanSch_ := false;
CapAppList_ := TStringList.Create;
CapAppList_.CaseSensitive := false;
SplitString(CAPTURE_APPS, '|', CapAppList_);
MonAppList_ := TStringList.Create;
MonAppList_.CaseSensitive := false;
BlockAppList_ := TStringList.Create;
BlockAppList_.CaseSensitive := false;
BlockAppWList_ := TStringList.Create;
bIsMonApp_ := false;
bIsBlockApp_ := false;
sMonApps_ := '';
sBlockApps_ := '';
ChangeDestinationUrl;
fas_ := nil;
if UseFasooDecrypt and not IsCJ_Affiliates then // CJ에서는 DLL 로드하지 않도록 수정 25_0812 09:12:16 kku
begin
if not ExistsKey(HKEY_CLASSES_ROOT, 'TypeLib\{D3135A34-059E-4A47-AAD4-0D84F41DC165}\1.0\0\win64') then
begin
// 롯데마트는 기본 64DLL이 등록되지 않음 24_1104 11:22:41 kku
// 다른 고객사는 확인필요...
var sFsDll: String := 'C:\Program Files\Fasoo DRM\CW-Packager\WorkPackagerV3.dll';
if not FileExists(sFsDll) then
sFsDll := GetRunExePathDir + DLL_FAS64;
if not FileExists(sFsDll) then
sFsDll := GetRunExePathDir + DIR_CONF + DLL_FAS64;
if FileExists(sFsDll) then
ExecutePath_hide('regsvr32.exe', Format('/s "%s"', [sFsDll]));
end;
var bInitFs: Boolean := true;
case CUSTOMER_TYPE of
CUSTOMER_WELFNI : SetDSD_CODE(DSD_CODE_WFNI);
CUSTOMER_WELFND : SetDSD_CODE(DSD_CODE_WFND);
else bInitFs := false;
end;
if bInitFs then
begin
var sFsDir: String := GetRunExePathDir + 'fsdinit';
if not DirectoryExists(sFsDir) then
sFsDir := GetRunExePathDir + DIR_CONF + 'fsdinit';
if DirectoryExists(sFsDir) then
begin
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
fas_ := TTgFasoo.Create(sFsDir);
end;
end;
end;
// 외부 DRM 사용준비
case CUSTOMER_TYPE of
CUSTOMER_KDNVN :
begin
var dwResult: DWORD := KCT_Init(GetRunExePathDir + DIR_CONF, 'kdnavien');
if dwResult <> RESULT_SUCCESS then
_Trace('Fail .. Init KESS .. Code=%x', [dwResult])
else
_Trace('Success .. Init KESS');
end;
CUSTOMER_CJONS :
begin
// 컴퓨터\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\TypeLib\{D3135A34-059E-4A47-AAD4-0D84F41DC165} - 여기에도 있다고 한다 25_0812 16:06:21 kku
if ExistsKey(HKEY_CLASSES_ROOT, 'TypeLib\{D3135A34-059E-4A47-AAD4-0D84F41DC165}\1.0\0\win64') then
begin
var sTemp: String := GetRunExePathDir + DIR_CONF + DLL_FAS64;
if FileExists(sTemp) then
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sTemp]));
end;
end;
end;
InitAgentInfo;
bSchRstVul_ := false;
LoadSchRstVul;
bRcvRemoveAgent_ := false;
bPreNacChk_ := false;
// 계정 암호 설정 정보를 가져오려면 최초 계정 정보를 가져와야 한다.
// 예) 원래 tocsg 계정을 kjkim으로 계정 변경 했는데 tocsg로 LogonUser()에 넣어야 잘 동작함 22_0526 10:17:05 kku
sDomain_ := '';
sAccount_ := '';
sUserName_ := '';
CheckHostAndUserInfo;
InitHttp;
if CUSTOMER_TYPE = CUSTOMER_DEV then
begin
if bFirstAip_ and (sAccount_ <> '') then
begin
_Trace('Force .. FindAipMdWnd(Dev)', 1);
FindAipMdWnd(true);
end;
end else
if IsSupportAIP and (sAccount_ <> '') then
begin
_Trace('Force .. FindAipMdWnd()', 1);
FindAipMdWnd(true);
end;
//mgkim bs1flt load
bFltCtrlInit_ := false;
FltCtrlPolicy_ := 0;
FltCtrl_ := TBs1fltControl.Create;
DcFltCtrlEnt_ := TDictionary<String,String>.Create;
// IgnoreDriverLoad
agentStatTime_:= FormatDateTime('yyyy-mm-dd"T"hh:nn:ss"+09:00"', Now);
_Trace('에이전트 시작 시간: %s',[agentStatTime_], 1);
SendStartAgentAuditLog;
if UseFltCtrl then
begin
var state : DWORD;
state := FltCtrl_.InitDriver(GetRunExePathDir, FltCtrlCallback);
if state = 0 then
begin
var PPid: DWORD;
var parentDir: string;
var programdataDir: string;
_Trace('장치 접근 제어 준비 .. OK', 1);
FltCtrl_.BeginControl(1);
//폴더 보호 적용
PPid:= GetProcessPPidByPid(GetCurrentProcessId());
parentDir:= ExtractFileDir(ExcludeTrailingPathDelimiter(GetRunExePathDir));
programdataDir := parentDir[1] + ':\ProgramData\Tocsg';
_Trace('장치 접근 제어 준비 .. 폴더 보호 시작 : %s, PPid : %d',[parentDir, PPid], 1);
FltCtrl_.SetPid(PG_PID_ALLOW, PPid);
FltCtrl_.SetPath(PG_PATH_BLACK, Pchar(programdataDir));
FltCtrl_.SetPath(PG_PATH_BLACK, Pchar(parentDir));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('eCrmHeHelper.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('KvCttSch.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('KvCttSchW.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('BSWmcr.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('BSOne-AIP-Decrypt14.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('BSOne-AIP-Decrypt.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('Bs1tri.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('eCrmInterCaller.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('filter.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('kvoop.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('tstxtract.exe'));
FltCtrl_.SetProcessPath(PG_PID_ALLOW, Pchar('FilterTestDotNet.exe'));
FltCtrl_.SetFileName(PG_PID_ALLOW, Pchar('eCrmHomeEdition.exe'));
FltCtrl_.SetFileName(PG_PID_ALLOW, Pchar('eCrmHomeEdition.ini'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('Bs1ovi.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('Bs1ovm.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('eCrmHeHelper.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('eCrmHeHelper32.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('Bs1shl.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('Bs1ovi64.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('libeay32.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('ssleay32.dll'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('bsonex64.sys'));
FltCtrl_.SetFileName(PG_FILE_ALLOW, Pchar('hpli.dat'));
_Trace('장치 접근 제어 준비 .. 폴더 보호 끝', 1);
FltCtrl_.FolderProtectControl(1);
//장치 차단
FltCtrl_.SetDeviceProtect(1);
FltCtrl_.SetHook(DWORD(BDC_USB), 1);
FltCtrl_.SetHook(DWORD(BDC_BLUETOOTH), 1);
//프로세스 보호
FltCtrl_.ProcessCreate(1);
FltCtrl_.ProcessProtect(1);
FltCtrl_.SetProcessProtectId(GetCurrentProcessId);
_Trace('프로세스 보호 끝', 1);
//레지스트리 보호
FltCtrl_.SetRegProtect(1);
bFltCtrlInit_ := true;
end else
_Trace('장치 접근 제어 준비 .. Fail : %d',[state],1);
end;
DeviceGuard_:= TDeviceGuardEngine.Create;
// DeviceGuard_.CreateDefaultPolicies;
// 에이전트 최초 상태정보 보낼때 참조할 수 있도록 미리 실행 시켜줌 23_0411 12:30:37 kku
TimerCheckOsConfig(nil);
TimerCheckSecurity(nil);
dwSLSaveTick_ := 0;
dwNacChkTick_ := 0;
ThdTaskTimer_ := TThdTaskTimer.Create(1000, true);
ThdTaskTimer_.AddTask(TimerCheckOsConfig, 1000, true);
ThdTaskTimer_.AddTask(TimerCheckServiceAvailable, 1000, true);
ThdTaskTimer_.AddTask(TimerCheckTemporaryConn, 1000, true);
ThdTaskTimer_.AddTask(TimerCheckExpPo, 1000, false);
ThdTaskTimer_.AddTask(TimerCheckSecurity, 3000, true);
ThdTaskTimer_.StartTimerThread;
ThdDevTaskTimer_ := TThdTaskTimer.Create(500, true);
ThdDevTaskTimer_.AddTask(TimerProcessDevTask, 500, true);
ThdDevTaskTimer_.StartTimerThread;
ThdStatusTimer_ := TThdTaskTimer.Create(1000, true);
dwStatusInterval_ := 2000;
case CUSTOMER_TYPE of
CUSTOMER_SHCD : dwStatusInterval_ := 4000;
CUSTOMER_KR : dwStatusInterval_ := 30000;
end;
if (PrefModel_.HealthCheckMilSec >= 1000) and
(PrefModel_.HealthCheckMilSec <> dwStatusInterval_) then
dwStatusInterval_ := PrefModel_.HealthCheckMilSec;
ThdStatusTimer_.AddTask(TimerProcessStatus, dwStatusInterval_, true, CUSTOMER_TYPE = CUSTOMER_KR);
ThdStatusTimer_.AddTask(TimerCheckConnect, 1000, true, false);
ThdStatusTimer_.StartTimerThread;
TThdInitProc.Create;
if HandleConfig_ <> nil then
begin
bWin7Ver_ := HandleConfig_.OsVersion = '7';
_Trace('WinVersion : %s (%s)', [HandleConfig_.OsVersion, HandleConfig_.OsMajorVer]);
end else
bWin7Ver_ := false;
UpdateCttSchVulState(true);
var sDT: String := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'EDT');
if (sDT <> '') then
begin
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'EDT');
if PrefModel_.IsPcStatePower or SleepPolicy.IsPcStatePower then
SendEventLogEx(MONITOR_PC_POWER, 'Power Off', false, JavaToDelphiDateTime(StrToIntDef(sDT, 0)));
end;
if PrefModel_.IsPcStatePower or SleepPolicy.IsPcStatePower then
begin
var dtBoot: TDateTime := GetBootTime;
sDT := FormatDateTime('yyyymmddhhnnss', dtBoot);
var sLastBDT: String := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'BDT');
if sDT <> sLastBDT then // 부팅 후 5분 이내 실행이면
begin
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'BDT', sDT, true);
SendEventLogEx(MONITOR_PC_POWER, 'Power On', false, dtBoot);
end;
end;
xPrintVer_ := '';
dtOneDay_ := 0;
EmpsUpDt := '';
PrtsUpDt := '';
BillUpDt := '';
MkcdUpDt := '';
LumpUpDt := '';
case CUSTOMER_TYPE of
CUSTOMER_DEV,
CUSTOMER_DEMO,
CUSTOMER_LGD,
CUSTOMER_WELFNI,
CUSTOMER_WELFND :
begin
ThdAppMon_ := TThdProcessWatch.Create;
ThdAppMon_.OnProcessWatchNotify := OnAppNotify;
ThdAppMon_.StartThread;
end;
CUSTOMER_KIMCHANG :
begin
var sXprtInfo: String := 'C:\ProgramData\bsoneprint\package.yml';
if FileExists(sXprtInfo) then
begin
var StrList: TStringList;
Guard(StrList, TStringList.Create);
StrList.LoadFromFile(sXprtInfo, TEncoding.UTF8);
var i, nPos: Integer;
var sLine: String;
for i := 0 to StrList.Count - 1 do
begin
sLine := StrList[i];
nPos := Pos('version:', sLine);
if nPos = 1 then
begin
Delete(sLine, 1, 8);
xPrintVer_ := Trim(sLine);
break;
end;
end;
var ini: TIniFile;
Guard(ini, TIniFile.Create(GetRunExePathDir + 'xPrint.ini'));
dtOneDay_ := ini.ReadDateTime('DateTime', 'xOneDayDT', 0);
EmpsUpDt := ini.ReadString('DateTime', 'EmpsUpDt', '');
PrtsUpDt := ini.ReadString('DateTime', 'PrtsUpDt', '');
BillUpDt := ini.ReadString('DateTime', 'BillUpDt', '');
MkcdUpDt := ini.ReadString('DateTime', 'MkcdUpDt', '');
LumpUpDt := ini.ReadString('DateTime', 'LumpUpDt', '');
// case GetServiceStatus('BSonePrintService') of
// SERVICE_RUNNING,
// SERVICE_START_PENDING : ;
// else begin
//
// ExecutePath_hide(sXprtPath, '-install');
// end;
// end;
end;
end;
end;
if NotUseUAC then
InstallOutlookPlugIn_forHD(hRcvHwnd_);
var ini: TIniFile;
var bExeRecover: Boolean;
var sPath := GetProgramFilesDir + DIR_TG + INI_FORCEHE;
if FileExists(sPath) then
begin
Guard(ini, TIniFile.Create(sPath));
bExeRecover := ini.ReadBool('Force', 'RecoverFile', true);
if bExeRecover then
begin
RecoverSvc_ := TRecoverService.Create;
RecoverSvc_.StartService;
TTgTrace.T('[MGKIM] RecoverSvc.. start', 2);
end;
end;
end;
Destructor TManagerService.Destroy;
begin
if VulService_ <> nil then
VulService_.StopWork;
// ThdStatusTimer_.StopTimerThread;
// ThdTaskTimer_.StopTimerThread;
FreeAndNil(ThdStatusTimer_);
FreeAndNil(ThdDevTaskTimer_);
FreeAndNil(ThdTaskTimer_);
if mtxDrmEnc_ <> nil then
FreeAndNil(mtxDrmEnc_);
if mtxDrmDec_ <> nil then
FreeAndNil(mtxDrmDec_);
if mtxPrtWater_ <> nil then
FreeAndNil(mtxPrtWater_);
// if mtxDrmOpen_ <> nil then
// FreeAndNil(mtxDrmOpen_);
// FreeAndNil(ThdMgRcver_);
// if ThdMsgAutoClose_ <> nil then
// FreeAndNil(ThdMsgAutoClose_);
FreeAndNil(UseOptCodeList_);
FreeAndNil(NoMatchList_);
FreeAndNil(ScreenBlockChkAppList);
FreeAndNil(ScreenLogoChkUrlList);
FreeAndNil(ScreenLogoChkAppList);
if DcOpenDoc_ <> nil then
FreeAndNil(DcOpenDoc_);
FreeAndNil(ThdFW_);
FreeAndNil(ThdEvent_);
FreeAndNil(ThdReact_);
DeactivePolicyAll;
FreeAndNil(UsbNoti_);
// FreeAndNil(MgCltFld_);
FreeAndNil(MgPwe_);
FreeAndNil(MgCttSchExp_);
FreeAndNil(MgCttSch_);
FreeAndNil(AgentModel_);
FreeAndNil(ActiveConnectList_);
FreeAndNil(ServerUrlList_);
FreeAndNil(HTTP_);
FreeANDNil(SSL_);
FreeAndNil(MonAppList_);
FreeAndNil(BlockAppWList_);
FreeAndNil(BlockAppList_);
FreeAndNil(CapAppList_);
FreeAndNil(PatternEntList_);
FreeAndNil(CbPatternEnts_);
FreeAndNil(MgPtn_);
// FreeAndNil(SSLCtx_);
FreeAndNil(IgrEjectDrives_);
if ThdOsUpdateScan_ <> nil then
FreeAndNil(ThdOsUpdateScan_);
if RecentDocWatch_ <> nil then
FreeAndNil(RecentDocWatch_);
FreeAndNil(NicService_);
FreeAndNil(VulService_);
if fas_ <> nil then
FreeAndNil(fas_);
FreeAndNil(DelayProcList_);
FreeAndNil(RecentFndList_);
if xPrintLogService_ <> nil then
FreeAndNil(xPrintLogService_);
// CoUninitialize;
gMgSvc := nil;
Inherited;
FltCtrl_.Cleanup;
FreeAndNil(FltCtrl_);
FreeAndNil(DeviceGuard_);
FreeAndNil(DcFltCtrlEnt_);
FreeAndNil(MgPrint_);
FreeAndNil(DriveList_);
FreeAndNil(UsbConnList_);
qWaterEnts_.OnNotify := OnWaterEntNotify;
FreeAndNil(qWaterEnts_);
FreeAndNil(PrefModel_);
FreeAndNil(PrefIdlModel_);
FreeAndNil(PrefVulModel_);
FreeAndNil(PrefOffline_);
FreeAndNil(PrefExpPolicy_);
FreeAndNil(HandleSecurity_);
FreeAndNil(HandleConfig_);
FreeAndNil(MgRule_);
FreeAndNil(FileExpEntList_);
FreeAndNil(MgCampn_);
FreeAndNil(CSDev_);
FreeAndNil(CS_);
FreeAndNil(RecoverSvc_);
end;
procedure TManagerService.Lock;
begin
CS_.Acquire;
end;
procedure TManagerService.Unlock;
begin
CS_.Release;
end;
procedure TManagerService.DevLock;
begin
CSDev_.Acquire;
end;
procedure TManagerService.DevUnlock;
begin
CSDev_.Release;
end;
procedure TManagerService.UpdateEmptyUsbInfo;
var
i: Integer;
dwLogicalDrv: DWORD;
sDrive: String;
begin
try
dwLogicalDrv := GetLogicalDrives;
for i := 0 to 31 do
if (dwLogicalDrv and (1 shl i)) > 0 then
begin
sDrive := Format('%s:\', [Char(Integer('A')+i)]);
if not DirectoryExists(sDrive) then
begin
if EmDriveList_.IndexOf(sDrive) = -1 then
EmDriveList_.Add(sDrive);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateEmptyUsbInfo()');
end;
end;
procedure TManagerService.CatchDriveSatate;
var
CurDrvList: TStringList;
i: Integer;
begin
try
if DriveList_.Count = 0 then
begin
DriveList_.CommaText := GetDrivesFromMask(GetLogicalDrives);
exit;
end;
Guard(CurDrvList, TStringList.Create);
CurDrvList.CommaText := GetDrivesFromMask(GetLogicalDrives);
// _Trace('DriveList_ = %s, CurDrvList = %s', [DriveList_.CommaText, CurDrvList.CommaText]);
for i := 0 to CurDrvList.Count - 1 do
if DriveList_.IndexOf(CurDrvList[i]) = -1 then
ProcessUSBArrival(CurDrvList[i]);
for i := 0 to DriveList_.Count - 1 do
if CurDrvList.IndexOf(DriveList_[i]) = -1 then
ProcessUSBRemove(DriveList_[i]);
DriveList_.CommaText := CurDrvList.CommaText;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CatchDriveSatate()');
end;
end;
procedure TManagerService.CheckHostAndUserInfo;
begin
try
if (sUserName_ = '') or (sDomain_ = '') or (sAccount_ = '') then
begin
// 로그인/로그아웃으로 사용자 계정 변경 감지를 위해 재활용하지 않는다 24_0207 17:31:06 kku
// if AgentModel_.AModelVer > 0 then
// begin
// // AD 사용 시 재활용하지 않도록 보완 24_0110 08:18:45 kku
// if not IsUseActiveDirectory then
// begin
// sDomain_ := AgentModel_.DomainName;
// sUserName_ := AgentModel_.UserName;
// sAccount_ := AgentModel_.Account;
// end;
// end;
if (sUserName_ <> '') and (sDomain_ <> '') and (sAccount_ <> '') then
exit;
if sDomain_ = '' then
begin
// 다이이찌산쿄에서 부팅 후 종종 계정이 짤려서 보이는 문제 확인됨. 보완 22_0707 08:54:50 kku
sDomain_ := StringReplace(GetUserNameFromExplorer, '\\', '', [rfReplaceAll]);
if (sDomain_ <> '') and (sAccount_ <> '') then
sUserName_ := ExtractFilePath(sDomain_) + sAccount_;
end;
if CUSTOMER_TYPE = CUSTOMER_KBIZ then
begin
if sAccount_ = '' then
begin
sAccount_ := GetRegValueAsString(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI', 'LastLoggedOnSAMUser');
if sAccount_ = '' then
sAccount_ := GetRegValueAsString(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI', 'LastLoggedOnUser');
if sAccount_ <> '' then
begin
sAccount_ := StringReplace(sAccount_, '.\', '', [rfReplaceAll]);
sAccount_ := ExtractFileName(sAccount_);
end;
end;
end;
if sAccount_ = '' then
begin
sAccount_ := WTS_GetCurrentUserName;
if IsUseActiveDirectory then
begin
// AD 환경 로그온 상태에서 WTS_GetCurrentUserName 안되는 경우가 있는지 확인이 필요하다.. 22_0905 08:49:45 kku
if sAccount_ <> '' then
sUserName_ := ExtractFilePath(sDomain_) + sAccount_
else
sUserName_ := sDomain_;
end else begin
if (sDomain_ <> '') and (sAccount_ <> '') then
sUserName_ := ExtractFilePath(sDomain_) + sAccount_;
end;
end;
if (sUserName_ = '') and (sDomain_ <> '') and (sAccount_ <> '') then
begin
sUserName_ := ExtractFilePath(sDomain_) + sAccount_;
AgentModel_.DomainName := sDomain_;
AgentModel_.Account := sAccount_;
AgentModel_.UserName := sUserName_;
AgentModel_.Save;
end;
if IsAccountEmpNo then
begin
if (sAccount_ <> '') and
(AgentModel_.EmpNo <> sAccount_) then
begin
_Trace('[06] 사번 변경, %s > %s', [AgentModel_.EmpNo, sAccount_]);
SendEventLogEx(LOG_CHANGE_EMPNO, Format('[Fixed] EmpId Changed. (%s > %s)', [AgentModel_.EmpNo, sAccount_]), false);
AgentModel_.EmpNo := sAccount_;
// AgentModel_.VpnInfo := AgentModel_.EmpNo;
AgentModel_.Save;
UpdateAgentInfo;
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CheckHostAndUserInfo()');
end;
end;
function TManagerService.HttpPost(sDest, sRqType, sParam: String; pnRespCode: PInteger = nil): String;
var
ss: TStringStream;
begin
Result := '';
nHttpError_ := 0;
sHttpError_ := '';
try
Guard(ss, TStringStream.Create(sParam, TEncoding.UTF8));
HTTP_.Request.CustomHeaders.Values['requestType'] := sRqType;
Result := HTTP_.Post(sDest, ss);
if (Result = '') and (HTTP_.ResponseCode = 200) then
Result := 'true';
if pnRespCode <> nil then
pnRespCode^ := HTTP_.ResponseCode;
except
on E: EIdReadTimeout do
begin
_Trace('HttpPost() .. ReadTimeout ..');
Result := POST_TIMEOUT;
sHttpError_ := E.Message;
nHttpError_ := GetLastError;
exit;
end;
on E: Exception do
begin
{$IFDEF TRACE1}
ETgException.TraceException(Self, E, Format('Fail .. HttpPost(), RqType=%s', [sRqType]));
{$ENDIF}
sHttpError_ := E.Message;
nHttpError_ := HTTP_.ResponseCode;
if pnRespCode <> nil then
pnRespCode^ := nHttpError_;
end;
end;
end;
function TManagerService.MakeComponentId(sTail: String): String;
var
nLen: Integer;
begin
sTail := StrsReplace(sTail, [';', ' '], '');
Result := sComName_ + '\' + FormatDateTime('yymmddhhnnss', Now) + '_' + sTail;
nLen := Length(Result);
if nLen > 60 then
begin
Result := Copy(Result, nLen - 59, 60);
// Result := THashSHA1.GetHashString(Result);
end;
end;
function TManagerService.GetCbFoundContentToJsonObj(sText: String; var sResultStr: String): ISuperObject;
var
i, nHits, nOrCnt, nAndCnt, nHighCnt: Integer;
sFound,
sResult: String;
O, OA: ISuperObject;
begin
Result := nil;
sResult := '';
sResultStr := '';
OA := TSuperObject.Create(stArray);
nOrCnt := 0;
nAndCnt := 0;
nHighCnt := 0;
try
for i := 0 to CbPatternEnts_.Count - 1 do
begin
nHits := TTgPcre.GetMatchValues(sText, CbPatternEnts_[i].GetSearchText, sFound);
if nHits > 0 then
begin
if bIsNewApi_ then
begin
var pRule: PRuleEnt := MgRule_.GetRuleFromId(CbPatternEnts_[i].Name);
if (pRule <> nil) and (pRule.nCnt > nHits) then
continue;
if CbPatternEnts_[i].RSeverity = ManagerPattern.rsHigh then
Inc(nHighCnt)
else if CbPatternEnts_[i].IsAnd then
Inc(nAndCnt)
else
Inc(nOrCnt);
SumString(sResult, Format('%s(%d)', [MgRule_.GetRuleNameFromId(CbPatternEnts_[i].Name), nHits]), ',')
end else
SumString(sResult, Format('%s(%d)', [CttCodeToStr(CbPatternEnts_[i].Name), nHits]), ',');
O := SO;
O.S['RULE_ID'] := CbPatternEnts_[i].Name;
O.S['CNT'] := IntToStr(nHits);
O.S['TEXT'] := RemoveOverlapWords(sFound);
OA.AsArray.Add(O);
end;
end;
if OA.AsArray.Length > 0 then
begin
if bIsNewApi_ then
begin
if (nHighCnt = 0) and (CbPatternEnts_.AndCount > 0) then
begin
// AND 갯수가 다르다면 X
if nAndCnt <> CbPatternEnts_.AndCount then
exit;
// OR가 조건으로 있는데 검출된 OR가 없다면 X
if (CbPatternEnts_.AndCount <> CbPatternEnts_.Count) and (nOrCnt = 0) then
exit;
end;
end;
sResultStr := sResult;
Result := OA;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CheckCbContent()');
end;
end;
function TManagerService.GetConnected: Boolean;
begin
Lock;
try
Result := bIsConnected_;
finally
Unlock;
end;
end;
procedure TManagerService.SetConnected(bVal: Boolean; bNewApi: Boolean);
begin
Lock;
try
if bIsConnected_ <> bVal then
begin
bIsConnected_ := bVal;
if bIsConnected_ then
begin
bIsNewApi_ := bNewApi;
if IsCJ_Affiliates then // CJ 사번 미인증이 오프라인 모드 24_1218 13:53:13 kku
bIsOffline_ := false;
dtSvrDisconn_ := 0;
dtApDisconn_ := 0;
dwNacChkTick_ := 0;
dtConnected_ := Now;
AgentModel_.LastConn := Now;
AgentModel_.Save;
_Trace('서버 연결됨', 1);
if CUSTOMER_TYPE = CUSTOMER_KIMCHANG then
begin
if not FileExists('C:\ProgramData\bsoneprint\data\xBil.dat') then
TThdRcvPolicy.Create(0);
if xPrintLogService_ = nil then
begin
xPrintLogService_ := TxPrintLogService.Create;
xPrintLogService_.StartService;
_Trace('xPrint 로그 처리 시작.', 1);
end;
end;
end else begin
if CUSTOMER_TYPE = CUSTOMER_KIMCHANG then
begin
if xPrintLogService_ <> nil then
begin
FreeAndNil(xPrintLogService_);
_Trace('xPrint 로그 처리 종료.', 1);
end;
end;
dtConnected_ := 0;
dtSvrDisconn_ := Now;
sPrintPatterns_ := '';
_Trace('서버 연결 해제됨', 1);
end;
end;
finally
Unlock;
end;
end;
function TManagerService.GetTemporaryConn: Boolean;
begin
Lock;
try
Result := bIsTemporaryConn_;
finally
Unlock;
end;
end;
procedure TManagerService.DoEjectCDROM;
var
i: Integer;
dwLogicalDrv: DWORD;
sDrive, sBlkSerial, sMsg: String;
IgrList: TStringList;
DriveInfo: TDriveInfo;
LogInfo: TLogInfo;
begin
try
if ModePolicy.CdromBlockKind = ubkBlock then
begin
Guard(IgrList, TStringList.Create);
IgrList.CaseSensitive := false;
if sCdException_ <> ModePolicy.CdromExcept then
begin
sCdException_ := ModePolicy.CdromExcept;
sCdExcepedList_ := '';
sFailCdBlock_ := '';
end;
SplitString(sCdException_, ';', IgrList);
dwLogicalDrv := GetLogicalDrives;
for i := 0 to 31 do
begin
sBlkSerial := '';
if (dwLogicalDrv and (1 shl i)) > 0 then
begin
sDrive := Format('%s:\', [Char(Integer('A')+i)]);
if GetDriveType(PChar(sDrive)) = DRIVE_CDROM then
begin
if FileService_ <> nil then
FileService_.DelDriveWatch(sDrive);
GetDriveDetail(sDrive, @DriveInfo);
// 일단 디스크인데 GetDriveType()이 DRIVE_CDROM로 나오는 현상이 있다고 함 (솔리데오) 24_0718 10:48:59 kku
if (DriveInfo.sClass <> '') and (DriveInfo.sClass.ToUpper <> 'CDROM') then
continue;
// 도시바 내장 디스크가 자꾸 차단이 되는 현상이 있다... (솔리데오) 24_0809 10:55:03 kku
if CompareText(DriveInfo.sFriendlyName, 'TOSHIBA DT01ACA100') = 0 then
continue;
if CUSTOMER_TYPE = CUSTOMER_GEC then
begin
// GEC에서 사원들에게 제공되는 C-Type USB 허브에서
// 드라이버 설치 경로가 CD/DVD로 잡히는데 차단이 안되는 현상 있음 24_0620 18:02:22 kku
var sVolName: String := UpperCase(GetVolumeName(sDrive));
// if (Pos('WCHUSBNIC', sVolName) > 0) and (DriveInfo.sSerial <> '') then
// IgrList.Add(DriveInfo.sSerial)
if Pos('WCHUSBNIC', sVolName) > 0 then
continue;
end;
// 실패한거 자꾸 차단 시도하지 않도록 위로 추가 24_1210 13:45:28 kku
// 가상 CDROM의 경우 초기 차단이 실패할 수 있다.
// 계속 반복해서 시도 하도록 아래에서 처리, 실패하면 한번만 로그 남도록 변경 25_0915 13:22:00 kku
// if Pos(sDrive, sFailCdBlock_) > 0 then
// continue;
if IgrList.Count > 0 then
begin
if IgrList.IndexOf(DriveInfo.sSerial) <> -1 then
continue;
end;
// if IsWin7Ver then
// begin
// if ForceEjectDrive(sDrive) then
// begin
// if DriveInfo.sSerial <> '' then
// sBlkSerial := DriveInfo.sSerial
// else
// sBlkSerial := sEmpNo_;
// end else
// sBlkSerial := FAIL_EJECT;
// end else begin
// sBlkSerial := EjectDrive(sDrive, IgrList, false, true);
//
//// if CUSTOMER_TYPE <> CUSTOMER_WELCAPI then
//// begin
//// // 아래꺼 하면... 인덱싱 색인이 사라지는 문제가 있다... 웰컴캐피탈에서 발견됨 24_1210 14:53:57 kku
//// if (sBlkSerial = '') or (sBlkSerial = FAIL_EJECT) then
//// sBlkSerial := EjectDrive2(sDrive, IgrList, false, true);
//// end;
//
// // 추가 24_1210 13:43:41 kku
// if (sBlkSerial = '') or (sBlkSerial = FAIL_EJECT) then
// begin
// if (DriveInfo.sSerial <> '') and ForceEjectDrive(sDrive) then
// sBlkSerial := DriveInfo.sSerial;
// end;
// end;
_Trace('.. sSerial(%s)', [DriveInfo.sSerial]);
sBlkSerial := DriveInfo.sSerial;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := PREVENT_CDROM;
LogInfo.sDevName := DriveInfo.sFriendlyName;
LogInfo.sDevSerial := DriveInfo.sSerial;
LogInfo.sDevClassId := DriveInfo.sClassGuid;
with DriveInfo do
begin
if sBlkSerial = FAIL_EJECT then
begin
if Pos(sDrive, sFailCdBlock_) = 0 then
begin
sMsg := Format('Fail .. CD/DVD Block : Drive=%s, Name=%s, Serial=%s',
[sDrive, sFriendlyName, sSerial]);
if bIsNewApi_ then
begin
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo);
end else
SendEventLog(URI_USER_ACTION, PREVENT_CDROM, sMsg, false);
SumString(sFailCdBlock_, sDrive, '|');
end;
end else
if sBlkSerial <> '' then
begin
if GetModePolicy.CDPopup then
PopupMessage(TYPE_MSG_PREVENT_CDROM, sDrive + '|' +
sFriendlyName + '|' + sBlkSerial);
sMsg := Format('CD/DVD Blocked : Drive=%s, Name=%s, Serial=%s',
[sDrive, sFriendlyName, sBlkSerial]);
if Pos(sDrive, sFailCdBlock_) > 0 then
begin
sFailCdBlock_ := StringReplace(sFailCdBlock_, sDrive + '|', '', [rfReplaceAll]);
sFailCdBlock_ := StringReplace(sFailCdBlock_, '|' + sDrive, '', [rfReplaceAll]);
end;
if bIsNewApi_ then
begin
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo);
end else
SendEventLog(URI_USER_ACTION, PREVENT_CDROM, sMsg);
end else begin
if Pos(sSerial, sCdExcepedList_) = 0 then
begin
if IsDivPopup and GetModePolicy.CdAllowPopup then
PopupMessage(TYPE_MSG_MONITOR_CDROM, sDrive);
SumString(sCdExcepedList_, sSerial, '|');
sMsg := Format('Excepted, CD/DVD Block : Drive=%s, Name=%s, Serial=%s',
[sDrive, sFriendlyName, sSerial]);
if bIsNewApi_ then
begin
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo);
end else
SendEventLog(URI_USER_ACTION, PREVENT_CDROM, sMsg, false);
end;
end;
end;
end;
end;
end;
end;
// else
// begin
// FltCtrl_.SetPolicy(DWORD(BDC_CDROM), DWORD(dsEnable), 0);
// end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoEjectCDROM()');
end;
end;
function FindAlyacScanWindow: HWND;
var
hMainDialog: HWND;
hCandidate, hStatic: HWND;
mainDialogClass: string;
mainDialogTitle: string;
validationStaticClass: string;
validationStaticText: string;
begin
Result := 0;
try
// 메인창 정보
mainDialogClass := '#32770';
mainDialogTitle := '검사';
validationStaticClass := 'Static';
validationStaticText := '이동식 디스크 검사';
hMainDialog := 0;
hCandidate := 0;
hCandidate := FindWindowEx(0, hCandidate, PChar(mainDialogClass), PChar(mainDialogTitle));
if hCandidate <> 0 then
begin
hStatic := FindWindowEx(hCandidate, 0, PChar(validationStaticClass), PChar(validationStaticText));
if hStatic <> 0 then
begin
Result := hCandidate;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. FindAlyacScanWindow()');
end;
end;
function CloseAlyacScanWindow: Boolean;
var
hMainDialog, hStopButton, hPopup, hYesButton: HWND;
hCandidate: HWND;
retries: Integer;
stopButtonText: string;
popupDialogClass: string;
popupDialogTitle: string;
popupYesButtonText: string;
begin
Result := false;
try
// 메인창 정보
stopButtonText := '중지(&S)';
// 팝업 창 정보
popupDialogClass := '#32770';
popupDialogTitle := '검사';
popupYesButtonText := '예(&Y)';
hMainDialog := 0;
// hCandidate := 0;
retries := 30;
while (hMainDialog = 0) and (retries > 0) do
begin
Sleep(100);
hMainDialog := FindAlyacScanWindow;
if hMainDialog <> 0 then
break;
Dec(retries);
end;
if hMainDialog = 0 then
exit;
// "중지(S)" 버튼 클릭 시도
hStopButton := FindWindowEx(hMainDialog, 0, 'Button', PChar(stopButtonText));
if hStopButton <> 0 then
begin
PostMessage(hStopButton, BM_CLICK, 0, 0);
end
else
begin
PostMessage(hMainDialog, WM_CLOSE, 0, 0);
end;
hPopup := 0;
retries := 30;
// var nTO: Integer := 0;
// while IsWindow(hMainDialog) do
// begin
// // 3
// if nTO > 10 then
// break;
while (hPopup = 0) and (retries > 0) do
begin
Sleep(100);
// FindWindowEx(0, hPrev, ...)는 hPrev *다음*의 최상위 창을 검색합니다.
hCandidate := 0;
while True do
begin
hCandidate := FindWindowEx(0, hCandidate, PChar(popupDialogClass), PChar(popupDialogTitle));
if hCandidate = 0 then // 더 이상 없음
Break;
// 찾은 창의 핸들(hCandidate)이 메인 창의 핸들(hMainDialog)과 다른지 확인
if hCandidate <> hMainDialog then
begin
// 찾았다
hPopup := hCandidate;
Break;
end;
end;
if hPopup <> 0 then
Break;
Dec(retries);
end;
if hPopup <> 0 then
begin
hYesButton := FindWindowEx(hPopup, 0, 'Button', PChar(popupYesButtonText));
if hYesButton <> 0 then
begin
PostMessage(hYesButton, BM_CLICK, 0, 0);
Result := true;
end;
end;
// Sleep(300);
// Inc(nTO);
// end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. CloseAlyacScanWindow()');
end;
end;
procedure TManagerService.DoEjectUsbDrive(sDrive: String; nType: Integer = -1);
var
sUsbExceptVender,
sIgrUsbSerialList,
sType, sBlkSerial, sVenders: String;
DriveInfo: TDriveInfo;
bNoLogPop: Boolean;
begin
try
DevLock;
try
if (sDrive = '') or (sDrive[1] = 'C') then
exit;
sUsbExceptVender := ModePolicy.UsbExceptVender;
sIgrUsbSerialList := ModePolicy.IgrUsbSerials;
if sExceptUsbDev_ <> (sUsbExceptVender + sIgrUsbSerialList) then
begin
sExceptUsbDev_ := sUsbExceptVender + sIgrUsbSerialList;
IgrEjectDrives_.Clear;
end;
if IgrEjectDrives_.IndexOf(sDrive) <> -1 then
exit;
if nType = -1 then
nType := GetDriveType(PChar(sDrive));
if nType = DRIVE_CDROM then
exit;
GetDriveDetail(sDrive, @DriveInfo);
if Pos('USB', UpperCase(DriveInfo.sSerial)) <> 1 then
begin
// USB 디바이스 아니면 넘기도록 보완
// 여기서 고정 디스크를 걸러준다 22_1109 08:09:41 kku
IgrEjectDrives_.Add(sDrive);
exit;
end;
bNoLogPop := DriveInfo.llSize = 0;
if bNoLogPop then
_Trace('빈 드라이브로 확인됨 .. Drive=%s, Size=0', [sDrive], 1);
sVenders := ModePolicy.UsbExceptVender;
if (sVenders <> '') and (DriveInfo.sFriendlyName <> '') then
begin
var VenderList: TStringList;
Guard(VenderList, TStringList.Create);
SplitString(UpperCase(sVenders), ';', VenderList);
sBlkSerial := UpperCase(DriveInfo.sFriendlyName);
var i: Integer;
for i := 0 to VenderList.Count - 1 do
if sBlkSerial.Contains(VenderList[i]) then
exit;
end;
//sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true);
if bNoLogPop then
exit;
sType := GetDriveTypeToStr(nType);
with DriveInfo do
begin
if sBlkSerial <> '' then
begin
if sBlkSerial = FAIL_EJECT then
begin
// SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_USB,
// Format('Fail .. USB Block : Name=%s, Drive=%s (%s), Type=%s, Serial=%s',
// [sFriendlyName, sDrive, ByteSizeToStr(llSize), sType, sBlkSerial]));
end else begin
sBlkSerial := ExtractFileName(sBlkSerial); // MAC 호환을 위해 VID, PID 등 제외 25_0324 09:54:27 kku
if ModePolicy.USBPopup then
begin
var sRegSerial: String := sBlkSerial;
if (UseFltCtrl) and ((FltCtrlPolicy_ = 1) or (FltCtrlPolicy_ = 2)) then
SumString(sRegSerial, GetFltCrltEntInfo(sDrive), '***');
PopupMessage(TYPE_MSG_PREVENT_USBDISCONN, sDrive + '*9*' +
ByteSizeToStr(llSize) + '*9*' + sFriendlyName + '*9*' + sType + '*9*' + sRegSerial);
end;
var sMsg: String := Format('USB Blocked : Name=%s, Drive=%s (%s), Type=%s, Serial=%s',
[sFriendlyName, sDrive, ByteSizeToStr(llSize), sType, sBlkSerial]);
if bIsNewApi_ then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_PREVENT_USB;
LogInfo.sDevName := sFriendlyName;
LogInfo.sDevSerial := sBlkSerial;
LogInfo.sDevClassId := sClassGuid;
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo);
end else
SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_USB, sMsg);
end;
end else
// if sRecentUsbDrv_ = sDrive then
begin
sRecentUsbDrv_ := '';
// D 드라이브를 계속 Eject 시도 하는데 이때 파일 감시도 계속 꺼진다.
// 그래서 보완... 22_1027 15:19:51 kku
if IgrEjectDrives_.IndexOf(sDrive) = -1 then
IgrEjectDrives_.Add(sDrive);
var sMsg: String := Format('Excepted, USB Block : Name=%s, Drive=%s (%s), Type=%s, Serial=%s',
[sFriendlyName, sDrive, ByteSizeToStr(llSize), sType, sSerial]);
if bIsNewApi_ then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := MONITOR_USB_EXCEPTED;
LogInfo.sDevName := sFriendlyName;
LogInfo.sDevSerial := sSerial;
LogInfo.sDevClassId := sClassGuid;
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo, false);
end else
SendEventLog(URI_USER_ACTION, MONITOR_USB_EXCEPTED, sMsg);
end;
end;
finally
DevUnlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoEjectUsbDrive()');
end;
end;
procedure TManagerService.DoEjectUsbDrives;
var
i: Integer;
dwLogicalDrv: DWORD;
begin
if ModePolicy.UsbBlockKind = ubkBlock then
begin
dwLogicalDrv := GetLogicalDrives;
for i := 0 to 31 do
begin
if (dwLogicalDrv and (1 shl i)) > 0 then
DoEjectUsbDrive(Format('%s:\', [Char(Integer('A')+i)]));
end;
end;
end;
procedure TManagerService.ProcessCampaign;
var
pEnt: PCampnEnt;
begin
try
if bTerminateThdScanSch_ then
begin
bTerminateThdScanSch_ := false;
if ThdScanSch_ <> nil then
FreeAndNil(ThdScanSch_);
end;
if ThdScanSch_ <> nil then
begin
case ThdScanSch_.WorkState of
tsStop,
tsFail :
begin
_Trace('Fail.. ProcessCampaign .. Result=%d', [Integer(ThdScanSch_.WorkState)]);
bTerminateThdScanSch_ := true;
bIsStopCampn_ := true;
llCampnEncCnt_ := ThdScanSch_.TotalEncCount;
llCampnEncFailCnt_ := ThdScanSch_.TotalEncFailCount;
if DlgEncCampn_ <> nil then
begin
DlgEncCampn_.Show;
DlgEncCampn_ := nil;
end;
end;
end;
exit;
end else
if bClearCampn_ then
begin
bClearCampn_ := false;
MgCampn_.ClearScanDate;
MgCampn_.Save;
end;
if pProcCampn_ <> nil then
exit;
StartCampaignTask(MgCampn_.GetWorkableCampaign(bIgrLastWorkCampn_));
if bIgrLastWorkCampn_ then
bIgrLastWorkCampn_ := false;
pEnt := MgCampn_.GetDelayNotiCampaign;
if pEnt <> nil then
begin
if pEnt.Info.bDelayNotice and (pEnt.Info.DelayCond = cdnOnce) then
pEnt.dtLastNoti := 0
else
pEnt.dtLastNoti := Now;
MgCampn_.Save;
pProcCampn_ := pEnt; // 구리지만 일단... 23_1114 15:35:16 kku
try
if pProcCampn_.Info.bNoActionVul then
SetSchRstVul(true);
PopupMessage(TYPE_MSG_CTTSCH_COMPLETE, '00:00:00|' + IntToStr(GetExistPiFileCount(pEnt.Info.sId)));
finally
pProcCampn_ := nil;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessCampaign()');
end;
end;
procedure TManagerService.UpdateInternalInfo;
var
i: Integer;
begin
try
{$IFNDEF DEBUG}
if not bInitRule_ and GetConnected then
begin
_Trace('UpdateInternalInfo() .. ContentRule Init ..', 1);
// 컨텐츠 룰을 서버에 등록된거와 같은지 체크 및 정리 25_0415 13:56:35 kku
// 이전 버전에서 컨텐츠 룰 삭제 시 반영이 안되는 문제가 있어서 추가함
// 추후에 삭제 해도됨
var sDest: String := StringReplace(sDestSvrUrl_, 'agentLogRequest.do', 'open-api/content-rules?type=idOnly', [rfReplaceAll]);
sDest := StringReplace(sDest, 'agentLogRequests.do', 'open-api/content-rules?type=idOnly', [rfReplaceAll]);
var ss: TStringStream;
Guard(ss, TStringStream.Create('', TEncoding.UTF8));
try
HTTP_.Get(sDest, ss);
if ss.DataString <> '' then
begin
var IdList: TStringList;
Guard(IdList, TStringList.Create);
var O: ISuperObject := SO(ss.DataString);
IdList.CommaText := O.S['ids'];
if IdList.Count > 0 then
begin
MgRule_.RefineRuleList(IdList);
bInitRule_ := true;
_Trace('UpdateInternalInfo() .. ContentRule Init .. OK', 1);
end;
end;
except
// ..
end;
end;
{$ENDIF}
if not bIsSendHWInfo_ then
SendHwInfo;
if PrefModel_.VpnAppName <> sVpnClient_ then
sVpnClient_ := PrefModel_.VpnAppName;
if (PrefModel_.NoticeContent <> '') and
(sNoticeContent_ <> PrefModel_.NoticeContent) then
begin
// 공지사항 변경 감지 후 팝업
sNoticeContent_ := PrefModel_.NoticeContent;
PopupMessage(TYPE_MSG_NOTIFICATION, sNoticeContent_);
end;
// if IsCheckPreventMac then // 전체 업체에서 사용가능 하도록 확대 22_0829 10:39:54 kku
if not IsNewApi or PrefModel_.CheckAllowMAC then
begin
// 보안모드 진입 시 허용되지 않은 MAC 제한 체크
if IsNewApi or (Length(PrefModel_.RestricMac) >= 12) then
begin
var MacList: TStringList;
var bAllowAccess: Boolean := false;
Guard(MacList, TStringList.Create);
if SplitString(PrefModel_.RestricMac, ';', MacList) > 0 then
begin
for i := 0 to MacList.Count - 1 do
begin
if (NicService_ <> nil) and NicService_.ContainMac(MacList[i]) then
begin
bAllowAccess := true;
break;
end;
end;
end;
bIsRestricMac_ := not bAllowAccess;
end else
bIsRestricMac_ := false;
end else
if bIsRestricMac_ then
bIsRestricMac_ := false;
if UpdateTick = 0 then
begin
var dtNow: TDateTime := Now;
if SecondsBetween(dtInfoFileCheck_, dtNow) >= 30 then
begin
dtInfoFileCheck_ := dtNow;
var sRes: String := GetRunExePathDir + DIR_CONF;
if not FileExists(sRes + DAT_AGENT) then
begin
_Trace('Lost .. agent info .. try recover.');
AgentModel_.Save;
end;
if bIsNewApi_ then
begin
if PrefModel_.Loaded and
not FileExists(sRes + NAME_PREF + '-' + PrefModel_.PoFileName + EXT_PROP) then
begin
_Trace('Lost .. policy info .. try recover-1');
PrefModel_.Save;
end;
if PrefIdlModel_.Loaded and
not FileExists(sRes + NAME_PREF + '-' + PrefIdlModel_.PoFileName + EXT_PROP) then
begin
_Trace('Lost .. policy info .. try recover-2');
PrefIdlModel_.Save;
end;
if PrefVulModel_.Loaded and
not FileExists(sRes + NAME_PREF + '-' + PrefVulModel_.PoFileName + EXT_PROP) then
begin
_Trace('Lost .. policy info .. try recover-3');
PrefVulModel_.Save;
end;
if PrefOffline_.Loaded and
not FileExists(sRes + NAME_PREF + '-' + PrefOffline_.PoFileName + EXT_PROP) then
begin
_Trace('Lost .. policy info .. try recover-4');
PrefOffline_.Save;
end;
if PrefExpPolicy_.Loaded and
not FileExists(sRes + NAME_PREF + '-' + PrefExpPolicy_.PoFileName + EXT_PROP) then
begin
_Trace('Lost .. policy info .. try recover-5');
PrefExpPolicy_.Save;
end;
end else
if not FileExists(sRes + DAT_PREF) then
begin
_Trace('Lost .. policy info .. try recover.');
PrefModel_.Save;
end;
if not FileExists(sRes + DAT_COMPANY) then
begin
_Trace('Lost .. company info .. try recover.');
var CompModel: TCompanyModel;
Guard(CompModel, TCompanyModel.Create);
CompModel.CustomerType := CUSTOMER_TYPE;
CompModel.CustomerSubType := CUSTOMER_SUB_TYPE;
CompModel.SvrDestList.AddStrings(ServerUrlList_);
CompModel.Save(sRes + DAT_COMPANY);
end;
end;
if (dtSoftInstTick_ = 0) or (HoursBetween(dtSoftInstTick_, dtNow) >= 4) then
begin
dtSoftInstTick_ := dtNow;
// 4시간에 한번 소프트웨어 설치 정보 전송 22_0819 11:14:46 kku
SendAppInstInfo;
end;
if (dtOldLogCheck_ = 0) or (HoursBetween(dtOldLogCheck_, dtNow) >= 12) then
begin
if gTrace <> nil then
gTrace.DeleteOldLogs(PrefModel_.LogKeepDays);
end;
if EmDriveList_.Count > 0 then
begin
var sDrive: String;
for i := EmDriveList_.Count - 1 downto 0 do
begin
sDrive := EmDriveList_[i];
if DirectoryExists(sDrive) then
begin
EmDriveList_.Delete(i);
ProcessUSBArrival(sDrive);
end;
end;
end;
CatchDriveSatate;
if not bCheckedFixDisk_ or ModePolicy.HdMonPopup then
begin
if bIsConnected_ or
(PrefModel_.OffLogKind <> olkNone) or
((CUSTOMER_TYPE = CUSTOMER_WELFND) and (GetProcessPidByName('SUSBClient') <> 0)) then
begin
// 주기적으로 체크하도록 변경
// PC가 켜져있는 상태에도 고정 디스크를 제거할 수 있다 23_1206 17:33:37 kku
bCheckedFixDisk_ := true;
var MgFixDisk: TManagerFixedDisk;
Guard(MgFixDisk, TManagerFixedDisk.Create);
var ChgDiskList: TDetectDiskList;
Guard(ChgDiskList, MgFixDisk.DetectChangeDisk);
if ModePolicy.DetectFixedDisk and (ChgDiskList.Count > 0) then
begin
var LogInfo: TLogInfo;
for i := 0 to ChgDiskList.Count - 1 do
begin
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := MONITOR_EMBEDDEDHARDDISK;
LogInfo.sDevName := ChgDiskList[i].DInfo.sFriendlyName;
LogInfo.sDevSerial := ChgDiskList[i].DInfo.sSerial;
LogInfo.sDevClassId := ChgDiskList[i].DInfo.sClassGuid;
LogInfo.sSummary := Format('[%s] Fixed Disk', [BooleanToStr(ChgDiskList[i].DType = ddtAdd, 'Add', 'Remove')]);
LogInfo.sResInfo := IntToStr(ChgDiskList[i].DInfo.llSize);
LogInfo.sAppPath := ChgDiskList[i].DInfo.sDrive;
LogInfo.sComment := Format('%s, %s', [ChgDiskList[i].DInfo.sClass, ChgDiskList[i].DInfo.sDesc]);
SendEventLogEx(@LogInfo);
if IsDivPopup and ModePolicy.HdMonPopup then
PopupMessage(TYPE_MSG_MONITOR_HARDDISK, LogInfo.sDevName);
// if ChgDiskList[i].DType = ddtAdd then
// ProcessUSBArrival(ChgDiskList[i].DInfo.sDrive)
// else
// ProcessUSBRemove(ChgDiskList[i].DInfo.sDrive);
end;
end;
end;
end;
// 레지스트리 정보 확인, 복구
if // (CUSTOMER_TYPE = CUSTOMER_ALADIN) and
(CountRegKeyValue(HKEY_LOCAL_MACHINE, REG_HE) < 9) then
begin
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'Version', SdkVersion, true);
SetRegValueInteger(HKEY_LOCAL_MACHINE, REG_HE, 'CT', CUSTOMER_TYPE, true);
SetRegValueInteger(HKEY_LOCAL_MACHINE, REG_HE, 'CST', CUSTOMER_SUB_TYPE, true);
SetRegValueInteger(HKEY_USERS, RecentUserSid + '\' + REG_HE, 'CT', CUSTOMER_TYPE, true);
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'EmpNo', AgentModel_.EmpNo, true);
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'UserName', AgentModel_.UserName, true);
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'HostName', AgentModel_.HostName, true);
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'DomainName', AgentModel_.DomainName, true);
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'LLO', IntToStr(DelphiToJavaDateTime(dtLastLogOn_)), true);
// if sLastPolicy_ <> '' then
begin
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'LP',
IntToStr(DelphiToJavaDateTime(StrToDateTime(sLastPolicy_))), true);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateInternalInfo()');
end;
end;
procedure TManagerService.OgnRecentFndList;
var
i, nTO: Integer;
dtNow: TDateTime;
begin
try
if RecentFndList_.Count = 0 then
exit;
dtNow := Now;
Lock;
try
for i := RecentFndList_.Count - 1 downto 0 do
begin
if (RecentFndList_[i].sMName <> '') and (CompareText(RecentFndList_[i].sMName, 'CiscoCollabHost.exe') = 0) then
nTO := 190
else
nTO := 4;
if SecondsBetween(RecentFndList_[i].dtReg, dtNow) > nTO then
RecentFndList_.Delete(i);
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OgnRecentFndList()');
end;
end;
function TManagerService.GetRecentFnd(sPath: String; var aEnt: TRecentFnd): Boolean;
var
i: Integer;
begin
Result := false;
try
if RecentFndList_.Count = 0 then
exit;
Lock;
try
for i := RecentFndList_.Count - 1 downto 0 do
begin
if CompareText(RecentFndList_[i].sPath, sPath) = 0 then
begin
aEnt := RecentFndList_[i]^;
Result := true;
exit;
end;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetRecentFnd()');
end;
end;
procedure TManagerService.AddDelayProcEnt(sId: String; dwDSec: DWORD);
var
pEnt: PDpEnt;
begin
try
New(pEnt);
pEnt.dwTick := GetTickCount;
pEnt.dwDSec := dwDSec;
pEnt.sId := sId;
Lock;
try
DelayProcList_.Add(pEnt);
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. AddDelayProcEnt()');
end;
end;
function TManagerService.HasDelayProcEntById(sId: String): Boolean;
var
i: Integer;
dwTick: DWORD;
pEnt: PDpEnt;
begin
Result := false;
try
dwTick := GetTickCount;
Lock;
try
for i := DelayProcList_.Count - 1 downto 0 do
begin
pEnt := DelayProcList_[i];
if (dwTick - pEnt.dwTick) > (pEnt.dwDSec * 1000) then
begin
DelayProcList_.Delete(i);
continue;
end;
if sId = pEnt.sId then
begin
Result := true;
exit;
end;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. HasDelayProcEntById()');
end;
end;
procedure TManagerService.AddRecentFnd(aEnt: TRecentFnd);
var
pEnt: PRecentFnd;
begin
try
New(pEnt);
pEnt^ := aEnt;
Lock;
try
RecentFndList_.Add(pEnt);
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. AddRecentFnd()');
end;
end;
procedure TManagerService.DelRecentFnd(sPath: String);
var
i: Integer;
begin
try
if RecentFndList_.Count = 0 then
exit;
Lock;
try
for i := RecentFndList_.Count - 1 downto 0 do
begin
if CompareText(RecentFndList_[i].sPath, sPath) = 0 then
begin
RecentFndList_.Delete(i);
exit;
end;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetRecentFnd()');
end;
end;
procedure TManagerService.ProcessStatusOld(bFailChangeDestUrl: Boolean = true);
function CheckUpdateAble(sNewVer, sCurVer: String): Boolean;
var
CurVers,
NewVers: TStringList;
ullNew, ullCur: ULONGLONG;
i: Integer;
begin
Result := false;
try
if sNewVer = sCurVer then
exit;
Guard(NewVers, TStringList.Create);
Guard(CurVers, TStringList.Create);
if SplitString(sNewVer, '.', NewVers) = 0 then
exit;
if SplitString(sCurVer, '.', CurVers) = 0 then
begin
Result := StrToIntDef(NewVers[0], 0) > StrToIntDef(sCurVer, 0);
exit;
end;
for i := 0 to NewVers.Count - 1 do
begin
if i >= CurVers.Count then
begin
Result := true;
exit;
end;
if StrToIntDef(NewVers[i], 0) < StrToIntDef(CurVers[i], 0) then
exit;
if StrToIntDef(NewVers[i], 0) > StrToIntDef(CurVers[i], 0) then
begin
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CheckUpdateAble()');
end;
end;
procedure ProcessCttSchSchedule(sOpt: String);
var
O: ISuperObject;
SchOpt: TFileScanOpt;
OptList: TStringList;
i, nPos: Integer;
dtScan,
dtRecent: TDateTime;
sName: String;
begin
if ThdScanSch_ <> nil then
begin
case ThdScanSch_.WorkState of
tsStop,
tsFail :
begin
_Trace('Fail.. ScanPersonalInfo .. Result=%d', [Integer(ThdScanSch_.WorkState)]);
bTerminateThdScanSch_ := true;
bIsStopCampn_ := true;
llCampnEncCnt_ := ThdScanSch_.TotalEncCount;
llCampnEncFailCnt_ := ThdScanSch_.TotalEncFailCount;
if DlgEncCampn_ <> nil then
begin
DlgEncCampn_.Show;
DlgEncCampn_ := nil;
end;
end;
end;
exit;
end;
if IsSchRstVul and (PrefModel_.PersonalInfoFileMax = 0) then
begin
DeleteDir(GetRunExePathDir + DIR_CTTSCHRST);
SetSchRstVul(GetPersonalInfoResults <> 0);
end;
if sOpt = '' then
exit;
// 개인정보 검사는 수면모드에서도 동작하도록 다시 동작 롤백
// 현재 서버에서 검사 정책 송신 시 한번만 하기 때문에 수면모드에서 무시하면
// 무시한 날은 개인정보 검사가 되지 않음 22_1121 09:26:30 kku
// {$IFNDEF DEBUG}
// if BS1ModeKind_ = hmkSleep then
// exit;
// {$ENDIF}
// if CUSTOMER_TYPE <> CUSTOMER_LOCAL then
// exit;
try
Guard(OptList, TStringList.Create);
SplitString(sOpt, '|', OptList);
if OptList.Count < 4 then
exit;
// 사용자 지정 패턴, 키워드에 | 값이 들어갈 수 있다..
// 이 값이 들어가면 값들이 옵션으로 나눠져서 제대로 설정한 값이 대입되지 않음..
// 그래서 한번 정제해준다, 서버 쪽에서 옵션 구분 값을 | 가 아닌 값으로 바꾸면 되긴 하는데..
// 일단 이렇게 처리한다. 22_1111 13:52:53 kku
for i := OptList.Count - 1 downto 0 do
begin
if (i - 1) = -1 then
break;
sOpt := OptList[i];
if not sOpt.StartsWith('scanid:') and not sOpt.StartsWith('scandate:') and
not sOpt.StartsWith('scantype:') and not sOpt.StartsWith('scanoption:') and
not sOpt.StartsWith('scandrm:') and not sOpt.StartsWith('scanzip:') and
not sOpt.StartsWith('custom__') and not sOpt.StartsWith('scansizelimit') and
not sOpt.StartsWith('scantimelimit') and not sOpt.StartsWith('exceptfolder') and
not sOpt.StartsWith('scanname') and not sOpt.StartsWith('scannamedisplay') and
not sOpt.StartsWith('scanoutlook') then
begin
OptList[i - 1] := OptList[i - 1] + '|' + sOpt;
end;
end;
ZeroMemory(@SchOpt, SizeOf(SchOpt));
for i := 0 to OptList.Count - 1 do
begin
sOpt := OptList[i];
if sOpt.StartsWith('scanid:') then
begin
Delete(sOpt, 1, 7);
SchOpt.sScanId := sOpt;
end else
if sOpt.StartsWith('scandate:') then
begin
Delete(sOpt, 1, 9);
dtScan := StrToDateTimeDef(sOpt, 0);
end else
if sOpt.StartsWith('scantype:') then
begin
Delete(sOpt, 1, 9);
SchOpt.bPartScan := sOpt.ToLower = 'part';
end else
if sOpt.StartsWith('scandrm:') then
begin
Delete(sOpt, 1, 8);
SchOpt.CttSchOpt.bIncDrm := sOpt.ToLower = 'true';
end else
if sOpt.StartsWith('scanzip:') then
begin
Delete(sOpt, 1, 8);
SchOpt.CttSchOpt.bIncZip := sOpt.ToLower = 'true';
end else
if sOpt.StartsWith('scanoption:') then
begin
Delete(sOpt, 1, 11);
SchOpt.sSchPtrns := StringReplace(sOpt, ';', '|', [rfReplaceAll]);
end else
if sOpt.StartsWith('scansizelimit:') then
begin
Delete(sOpt, 1, 14);
SchOpt.nLimitSizeMB := StrToIntDef(sOpt, 0);
end else
if sOpt.StartsWith('scantimelimit:') then
begin
Delete(sOpt, 1, 14);
SchOpt.nSchTimeoutSec := StrToIntDef(sOpt, 0);
if SchOpt.nSchTimeoutSec = 0 then
SchOpt.nSchTimeoutSec := 20;
end else
if sOpt.StartsWith('exceptfolder:') then
begin
Delete(sOpt, 1, 13);
SchOpt.sIgrWordPath := StrListToCommaStr(sOpt, '|', false, true);
end else
if sOpt.StartsWith('scanname:') then
begin
Delete(sOpt, 1, 9);
SchOpt.sSchTitle := sOpt;
end else
if sOpt.StartsWith('scannamedisplay:') then
begin
Delete(sOpt, 1, 16);
SchOpt.bShowSchTitle := sOpt.ToLower = 'true';
// end else
// if sOpt.StartsWith('scanoutlook:') then
// begin
// Delete(sOpt, 1, 12);
// SchOpt.bSchOutlook_ := sOpt.ToLower = 'true';
end else
if sOpt.StartsWith('custom__') then
begin
sOpt := StringReplace(sOpt, ';', '|', [rfReplaceAll]);
sOpt := StringReplace(sOpt, #13#10, '|', [rfReplaceAll]);
Delete(sOpt, 1, 8);
nPos := Pos('__keyword:', sOpt);
if nPos = 0 then
nPos := Pos('__pattern:', sOpt);
if nPos > 0 then
begin
sName := Copy(sOpt, 1, nPos - 1);
Delete(sOpt, 1, nPos + 9); // 9는 __pattern: 또는 __keyword: 길이 - 1
SumString(SchOpt.CttSchOpt.sCustomKwdPtrn, sName + '::' + sOpt, '**');
end;
end;
end;
if SchOpt.sScanId = '' then
begin
_Trace('Fail .. ProcessCttSchSchedule() .. No ScanId');
exit;
end;
if dtScan = 0 then
begin
_Trace('Fail .. ProcessCttSchSchedule() .. No ScanDate');
exit;
end;
if (SchOpt.sSchPtrns = '') and (SchOpt.CttSchOpt.sCustomKwdPtrn = '') then
begin
_Trace('Fail .. ProcessCttSchSchedule() .. No ScanPatterns');
exit;
end;
if SchOpt.sSchPtrns = '' then
begin
// 여기 비어 있으면 "ptnsch.dat" 기본 체크된 패턴이 검색되므로 임의로 채워준다. 22_1114 16:29:51 kku
SchOpt.sSchPtrns := '<Empty>';
end;
dtRecent := MgCttSch_.GetTastRecentDT(SchOpt.sScanId);
if dtRecent <> 0 then
begin
if CompareDate(dtScan, dtRecent) <> 1 then
exit;
if SchOpt.bPartScan then
SchOpt.dtRecent := MgCttSch_.GetTastRecentLcDT(SchOpt.sScanId);
end else
SchOpt.bPartScan := false;
_Trace('ProcessCttSchSchedule() Begin .. RcvScanDate=%s, ScanId=%s', [DateTimeToStr(dtScan), SchOpt.sScanId]);
var PO: TPrefModel := GetModePolicy;
SchOpt.sScanExt := DOC_EXTS;
SchOpt.nLangId := 1;
SchOpt.nLimitSizeMB := PO.CfLimitMB;
SchOpt.nSchTimeoutSec := PO.CfTimeoutSec;
SchOpt.CttSchOpt.nUnzipDepth := PO.CfZipDepth;
SchOpt.CttSchOpt.hRcvHwnd := hRcvHwnd_;
SchOpt.CttSchOpt.nWorkPriority := -1;
SchOpt.CttSchOpt.sKvMdPath := GetRunExePathDir + 'bin\';
StartPiSchTask(SchOpt, dtScan);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessCttSchSchedule()');
end;
end;
procedure ProcessCltFldSchedule;
var
bCollectAble: Boolean;
FileCollectPlan: TFileCollectPlan;
FileCollectKind: TFileCollectKind;
sDate: String;
dtNow: TDateTime;
begin
try
if ThdCltFld_ <> nil then
begin
case ThdCltFld_.WorkState of
tsCompleted :
begin
FreeAndNil(ThdCltFld_);
AgentModel_.RecentCltFldDT := Now;
AgentModel_.Save;
end;
tsStop,
tsFail :
end;
exit;
end;
FileCollectPlan := PrefModel_.FileCollectPlan;
FileCollectKind := PrefModel_.FileCollectKind;
if (FileCollectPlan = fcpNone) or
(FileCollectKind = fckNone) then
begin
AgentModel_.RecentCltFldDT := 0;
AgentModel_.Save;
exit;
end;
// {$IFDEF DEBUG}
// AgentModel_.RecentCltFldDT := 0;
// {$ENDIF}
if GetModeKind = hmkSleep then
exit;
dtNow := Now;
if (AgentModel_.RecentCltFldDT <> 0) and
IsSameDay(TDate(AgentModel_.RecentCltFldDT), TDate(dtNow)) then
exit;
if PrefModel_.FileCollectDate = 0 then
exit;
if FileCollectKind = fckFile then
begin
if not FileExists(PrefModel_.TgFileCollect) then
exit;
end else begin
if not DirectoryExists(PrefModel_.TgFileCollect) then
exit;
end;
case FileCollectPlan of
fcpNone : exit;
fcpOnce : bCollectAble := IsSameDay(PrefModel_.FileCollectDate, TDate(dtNow));
fcpWeek : bCollectAble := DayOfWeek(PrefModel_.FileCollectDate) = DayOfWeek(TDate(dtNow));
fcpMonthDate : bCollectAble := DayOf(PrefModel_.FileCollectDate) = DayOf(dtNow);
fcpMonthWeek : bCollectAble := (WeekOfTheMonth(PrefModel_.FileCollectDate) = WeekOfTheMonth(dtNow)) and
(DayOfWeek(PrefModel_.FileCollectDate) = DayOfWeek(TDate(dtNow)));
end;
// {$IFDEF DEBUG}
// bCollectAble := true;
// {$ENDIF}
if bCollectAble then
begin
_Trace('Start .. Collect files from folder="%s"', [PrefModel_.TgFileCollect], 1); // todo : 나중에 감춰준다 22_1101 15:47:15 kku
ThdCltFld_ := TThdSendFilesFromDir.Create(PrefModel_.TgFileCollect, FileCollectKind = fckFolderIncSub);
ThdCltFld_.StartThread;
end else begin
AgentModel_.RecentCltFldDT := dtNow;
AgentModel_.Save;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessCltFldSchedule()');
end;
end;
procedure ProcessUpdate(sNewVer: String);
var
sUrl,
sPtPath: String;
fs: TFileStream;
nOldTO: Integer;
begin
try
sUrl := StringReplace(DestServerUrl, 'agentLogRequest.do', 'agentDownloadReq/', [rfReplaceAll]);
sUrl := StringReplace(sUrl, 'agentLogRequests.do', 'agentDownloadReq/', [rfReplaceAll]) + DOWNLOAD_TYPE_PATCH;
nOldTO := HTTP_.ReadTimeout;
HTTP_.ReadTimeout := 120000;
sPtPath := GetProgramFilesDir + DIR_TG;
fs := TFileStream.Create(sPtPath + 'patch.zip', fmCreate);
try
HTTP_.Get(sUrl, fs);
Sleep(500);
if FileExists(sPtPath + ZIP_PT) then
begin
FreeAndNil(fs);
if GetFileSize_path(sPtPath + ZIP_PT) = 0 then
begin
DeleteFile(PChar(sPtPath + ZIP_PT));
exit;
end;
TZipFile.ExtractZipFile(sPtPath + ZIP_PT, sPtPath);
DeleteFile(PChar(sPtPath + ZIP_PT));
if FileExists(sPtPath + EXE_PT) then
begin
SendEventLog(URI_USERUPDATE, SYSEVT_AGENT_PATCH, 'Patch Downloaded : ' + sNewVer);
ExecuteApp(sPtPath + EXE_PT, '', SW_HIDE);
UpdateTick := GetTickCount;
end;
end;
finally
if fs <> nil then
FreeAndNil(fs);
HTTP_.ReadTimeout := nOldTO;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessUpdate()');
end;
end;
var
sIp, sMac, sEulaCon,
sHostName, sScanPolicy,
sDirCollect,
sAvInfo, sAsInfo, sFwInfo, sRes: String;
O, OSub: ISuperObject;
i: Integer;
bChangedPolicy: Boolean;
dtNow: TDateTime;
NewAgentInfo: TCheckAgentInfo;
bChangeAgentInfo: Boolean;
Label
LB_ProcessPolicy;
function IsChangeAgentInfo: Boolean;
begin
Result := true;
with AgentInfo do
begin
if sAgentId <> NewAgentInfo.sAgentId then exit;
if sIp <> NewAgentInfo.sIp then exit;
if sIps <> NewAgentInfo.sIps then exit;
if sMAC <> NewAgentInfo.sMAC then exit;
if sHostName <> NewAgentInfo.sHostName then exit;
// if sStatusType <> NewAgentInfo.sStatusType then exit;
if sEulaCon <> NewAgentInfo.sEulaCon then exit;
if sLocation <> NewAgentInfo.sLocation then exit;
if sPwSet <> NewAgentInfo.sPwSet then exit;
if sPwSetTermOk <> NewAgentInfo.sPwSetTermOk then exit;
if sScrnLock <> NewAgentInfo.sScrnLock then exit;
if sOsVer <> NewAgentInfo.sOsVer then exit;
if sAvInfo <> NewAgentInfo.sAvInfo then exit;
// if sAsInfo <> NewAgentInfo.sAsInfo then exit;
if sFwInfo <> NewAgentInfo.sFwInfo then exit;
if sOsSafe <> NewAgentInfo.sOsSafe then exit;
if sPatchExist <> NewAgentInfo.sPatchExist then exit;
if sAvSafe <> NewAgentInfo.sAvSafe then exit;
if sAvUptodate <> NewAgentInfo.sAvUptodate then exit;
if sFwSafe <> NewAgentInfo.sFwSafe then exit;
if sPiSafe <> NewAgentInfo.sPiSafe then exit;
// if sSafeBlock <> NewAgentInfo.sSafeBlock then exit;
if sEmpNo <> NewAgentInfo.sEmpNo then exit;
// if bSafePcSHCD <> NewAgentInfo.bSafePcSHCD then exit;
if sModeName <> NewAgentInfo.sModeName then exit;
end;
Result := false;
end;
var
bConnected,
bPrevConnected: Boolean;
SecuApp: TSecureApp;
begin
try
sScanPolicy := '';
sDirCollect := '';
// 접속 상태 처리를 TimerCheckConnect()에서 여기로 옮김 23_0324 12:04:45 kku
// if not Connected then
// goto LB_ProcessPolicy;
if sEmpNo_ = '' then
begin
_Trace('StatusOld() Init .. Empty EmpNo ..');
Sleep(3000);
exit;
end;
sHostName := sUserName_;
if sHostName = '' then
begin
_Trace('StatusOld() Init .. Empty HostName?? .. GetComAct=%s', [GetComName + '\' + GetAccount]);
Sleep(5000);
exit;
// sHostName := GetComName + '\' + GetAccount;
end;
if IsOfflineMode then
exit;
// if IsServiceAvailable and
// ((VulService_.IsSafeMode and VulService_.IsWhiteApp) or IsTemporaryConn) then
// sStatusType := 'Connected'
// else
// sStatusType := 'Disconnected';
SecuApp := HandleSecurity_.GetMainAv;
if (SecuApp <> nil) and (SecuApp.Name <> '') then
begin
sAvInfo := SecuApp.Name + MODEL_SEPARATOR + // MODEL_SEPARATOR +
SecuApp.Path + MODEL_SEPARATOR + SecuApp.Timestamp;
end else
sAvInfo := 'null';
SecuApp := HandleSecurity_.GetMainAs;
if (SecuApp <> nil) and (SecuApp.Name <> '') then
begin
sAsInfo := SecuApp.Name + MODEL_SEPARATOR +
SecuApp.Path + MODEL_SEPARATOR + SecuApp.Timestamp;
end else
sAsInfo := 'null';
SecuApp := HandleSecurity_.GetMainFw;
if (SecuApp <> nil) and (SecuApp.Name <> '') then
begin
sFwInfo := SecuApp.Name + MODEL_SEPARATOR +
SecuApp.Path + MODEL_SEPARATOR + SecuApp.Timestamp;
end else
sFwInfo := 'null';
sEulaCon := 'disagree';
if AgentModel_.EulaDT <> 0 then
sEulaCon := FormatDateTime('yyyy-mm-dd hh:nn:ss', AgentModel_.EulaDT);
sIp := NicService_.GetIP;
sMac := NicService_.GetMAC;
NewAgentInfo.sAgentId := sAgentId_;
NewAgentInfo.sIp := sIp;
NewAgentInfo.sIps := NicService_.IpAll;
NewAgentInfo.sMAC := sMac;
if IsUseHostNameOnly then
NewAgentInfo.sHostName := sComName_
else
NewAgentInfo.sHostName := sHostName;
// NewAgentInfo.sStatusType := sStatusType;
NewAgentInfo.sEulaCon := sEulaCon;
if PrefModel_.PolicyGroup <> '' then
NewAgentInfo.sLocation := PrefModel_.PolicyGroup
else
NewAgentInfo.sLocation := PrefModel_.PolicyName;
NewAgentInfo.sPwSet := BooleanToStr(VulService_.IsPasswordSet, 'true', 'false');
NewAgentInfo.sPwSetTermOk := BooleanToStr(VulService_.IsPasswordSetTermOk, 'true', 'false');
NewAgentInfo.sScrnLock := BooleanToStr(VulService_.IsScreenSaverSet, 'true', 'false');
if HandleConfig_.OsMajorVer <> '' then
NewAgentInfo.sOsVer := Format('%s (%s)', [HandleConfig_.OsVersion, HandleConfig_.OsMajorVer]) // VulService_.OsVersion;
else
NewAgentInfo.sOsVer := HandleConfig_.OsVersion;
NewAgentInfo.sAvInfo := sAvInfo;
// NewAgentInfo.sAsInfo := sAsInfo;
NewAgentInfo.sFwInfo := sFwInfo;
NewAgentInfo.sOsSafe := BooleanToStr(VulService_.IsOsSafe, 'true', 'false');
NewAgentInfo.sPatchExist := BooleanToStr(VulService_.IsOsPatchUptoDate, 'true', 'false');
NewAgentInfo.sAvUptodate := BooleanToStr(VulService_.IsAntiVirusUpToDate, 'true', 'false');
NewAgentInfo.sAvSafe := BooleanToStr(VulService_.IsAvOn, 'true', 'false');
NewAgentInfo.sFwSafe := BooleanToStr(VulService_.IsFirewallOn, 'true', 'false');
NewAgentInfo.sPiSafe := BooleanToStr(bSchRstVul_, 'false', 'true');
case GetModeKind of
hmkSleep : NewAgentInfo.sModeName := 'Sleep';
hmkSecurity : NewAgentInfo.sModeName := 'Secu';
hmkVulnerability : NewAgentInfo.sModeName := 'Vul';
hmkOffline : NewAgentInfo.sModeName := 'Offline';
hmkException : NewAgentInfo.sModeName := 'Exption';
end;
// NewAgentInfo.sSafeBlock := BooleanToStr(VulService_.IsSafeMode, 'true', 'false');
NewAgentInfo.sEmpNo := sEmpNo_;
// NewAgentInfo.bSafePcSHCD := (CUSTOMER_TYPE = CUSTOMER_SHCD) and FileExists(GetRunExePathDir + EXE_SafePCUninst);
O := SO;
bPrevConnected := GetConnected;
bChangeAgentInfo := IsChangeAgentInfo;
// 공통
O.S['mwAKey_AGENTID'] := NewAgentInfo.sAgentId;
O.S['mwAKey_LOCATION'] := NewAgentInfo.sLocation;
O.S['mwAKey_EMPNO'] := NewAgentInfo.sEmpNo;
O.S['mwAKey_IP'] := NewAgentInfo.sIp;
O.S['mwAKey_HOSTNAME'] := NewAgentInfo.sHostName;
O.S['mwAKey_MAC'] := NewAgentInfo.sMAC;
O.S['KEY_MODE'] := NewAgentInfo.sModeName;
if not bPrevConnected or bChangeAgentInfo then
begin
O.S['MODEL_ID'] := NewAgentInfo.sAgentId;
O.S['mwAKey_IPS'] := NewAgentInfo.sIps;
// O.S['mwAKey_STATUS'] := NewAgentInfo.sStatusType;
O.S['mwAKey_COLLASTCONN'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
O.S['mwAKey_COLVERSION'] := SdkVersion;
O.S['mwAKey_EULACONFIRMED'] := NewAgentInfo.sEulaCon;
O.S['mwAKey_PWDSET'] := NewAgentInfo.sPwSet;
if NewAgentInfo.sPwSetTermOk <> 'true' then
begin
var nOver: Integer := DaysBetween(Now, dtLastChangePW_);
if (nOver > 0) and (nOver > PrefModel_.PwChkTermDay) then
O.S['mwAKey_PWDEXPIRED'] := IntToStr(nOver - PrefModel_.PwChkTermDay)
else
O.S['mwAKey_PWDEXPIRED'] := 'true';
end else
O.S['mwAKey_PWDEXPIRED'] := NewAgentInfo.sPwSetTermOk;
O.S['mwAKey_SCRNLOCK'] := NewAgentInfo.sScrnLock;
O.S['mwAKey_OSVER'] := NewAgentInfo.sOsVer;
O.S['mwAKey_PATCHES'] := 'null';
O.S['mwAKey_AVINFORM'] := NewAgentInfo.sAvInfo;
// _Trace('NewAgentInfo.sAvInfo="%s"', [NewAgentInfo.sAvInfo]);
O.S['mwAKey_ASINFORM'] := 'null'; // NewAgentInfo.sAsInfo;
O.S['mwAKey_FIREWALLINFO'] := NewAgentInfo.sFwInfo;
O.S['mwAKey_SOFTWAREINFO'] := 'null';
O.S['mwAKey_ADDEULACONFIRM'] := 'false';
O.S['mwAKey_OSSAFE'] := NewAgentInfo.sOsSafe;
O.S['mwAKey_PATCHEXIST'] := NewAgentInfo.sPatchExist;
O.S['mwAKey_AVSAFE'] := NewAgentInfo.sAvSafe;
O.S['mwAKey_ASSAFE'] := 'true';
O.S['mwAKey_FWSAFE'] := NewAgentInfo.sFwSafe;
O.S['mwAKey_PISAFE'] := NewAgentInfo.sPiSafe;
// O.S['mwAKey_SAFEBLOCKSETTING'] := NewAgentInfo.sSafeBlock;
// O.S['mwAKey_VPNINFO'] := NewAgentInfo.sEmpNo;
// O.S['mwAKey_AGENTTYPE'] := ''; // PC, VDI 여부
// if NewAgentInfo.bSafePcSHCD then O.S['mwAKey_SAFEPC'] := 'true';
end else begin
O.S['KEY_LASTPOLICY'] := sLastPolicy_;
end;
// {$IFDEF DEBUG} SaveJsonObjToFile(O, 'c:\a.json'); {$ENDIF}
sRes := HttpPost(sDestSvrUrl_, '123120', O.AsString);
// 접속 상태 처리를 TimerCheckConnect()에서 여기로 옮김 23_0324 12:04:45 kku
try
// bConnected := (sRes <> '') or (sRes <> 'true');
bConnected := (sRes = POST_TIMEOUT) or
( (sRes <> '') and (sRes <> 'true') and (sRes <> '404') and sRes.Contains('KEY_LASTPOLICY') );
if not bConnected then
begin
if not bPrevConnected then
begin
if bFailChangeDestUrl then
ChangeDestinationUrl;
end else
SetConnected(false, false);
end else
if not bPrevConnected then
begin
if (sRes = POST_TIMEOUT) or
(Pos('mwPKey_LOCNAME', sRes) = 0) then // 2.7에서 요청시 "KEY_LASTPOLICY" 키 값만 떨어지는데 접속해제 거르기 위해 추가
begin
bConnected := false;
if bFailChangeDestUrl then
ChangeDestinationUrl; // 음... 타임아웃 되도 이전 접속이 false라면 접속 정보 변경 시도해준다 23_0608 13:49:09 kku
end else
SetConnected(true, false);
end;
if bConnected then
begin
if VulService_.IsVpnOn and bDoEmpNoCheck_ then
begin
// 사번검증을 통해 미검증 시 보안모드 진입을 막을 예정이었으나...
// 일단 그렇게까지 동작하지 않도록 함 22_0531 16:04:58 kku
bIsEmpNoOk_ := VerifyEmpNo(DestServerUrl, HTTP_, sEmpNo_);
bDoEmpNoCheck_ := false;
if not bIsEmpNoOk_ then
begin
PopupMessage(TYPE_MSG_VUL_EMPNO);
if CUSTOMER_TYPE = CUSTOMER_KFTC then
begin
// 금융결제원의 경우 사번이 유효하지 않은 경우 (인사연동 안된 사번)
// 보안모드 차단 되도록 기능 추가 23_0425 12:52:05 kku
VulService_.SetDisconnect(true);
end;
end;
end else
bIsEmpNoOk_ := true;
end;
except
_Trace('Fail .. ConnectionCheck');
end;
if not bConnected or (sRes = POST_TIMEOUT) then
goto LB_ProcessPolicy;
// 접속 상태 처리 끝 ---------------------------------------------------------
try
O := SO(sRes);
if O = nil then
begin
_Trace('Invalid PolicyData ... 2');
exit;
end;
except
_Trace('Invalid PolicyData ... 1');
exit;
end;
// SaveJsonObjToFile(O, 'c:\b.json');
if CUSTOMER_TYPE = CUSTOMER_SHCD then
begin
// if ( (sEmpNo_ = '') or (CompareText(sEmpNo_, 'Empty') = 0) ) and
// ( (O.S['mwPKey_EMPNO'] <> '') and (CompareText(O.S['mwPKey_EMPNO'], 'Empty') <> 0) ) then
// 서버에서 내려주는 사번과 항상 동일하게 맞추도록 보완 23_0328 15:36:34 kku
var sSvrEmpNo: String := O.S['mwPKey_EMPNO'];
if (sSvrEmpNo <> '') and (sSvrEmpNo <> sEmpNo_) then
begin
// _Trace('Change EmpNo .. %s > %s', [sEmpNo_, sSvrEmpNo]);
_Trace('[07] 사번 변경, %s > %s', [sEmpNo_, sSvrEmpNo]);
SendEventLogEx(LOG_CHANGE_EMPNO, Format('[Server] EmpId Changed. (%s > %s)', [sEmpNo_, sSvrEmpNo]), false);
AgentModel_.EmpNo := sSvrEmpNo;
AgentModel_.Save;
UpdateAgentInfo;
end;
end;
if O.S['KEY_QUARANTINE'].ToLower = 'true' then
begin
_Trace('격리 해제된 파일 발견', 1);
ProcessReleaseQuarantineFiles;
end;
// {$IFDEF DEBUG} SaveJsonObjToFile(O, 'c:\s.json'); {$ENDIF}
if O.S['mwPKey_LOCNAME'] = '' then
begin
// 시그널 전송이 와도 정책 적용 되도록 보완
// UpdatePolicyActive() 안에 정책 스레드 활성화도 있지만 직접 처리하는 정책도 있음 23_0322 07:53:21 kku
// TimerCheckServiceAvailable()로 이동 23_0322 08:01:46 kku
// UpdatePolicyActive(ModePolicy);
// ReadTimeout으로 결과를 못가져왔을때 처리 22_0615 14:38:06 kku
// _Trace('Faill .. ReadPolicy .. Empty?=[%s]', [O.AsString]);
exit;
end;
_Trace('정책 수신됨', 1);
if CUSTOMER_TYPE = CUSTOMER_KOCES then
begin
if sUName_ = '' then
begin
// 사용자 이름 가져오기 추가 23_0327 16:34:28 kku
if (dwUNameChkTick_ = 0) or ((GetTickCount - dwUNameChkTick_) > 7200000) then // 2시간 마다 체크
begin
dwUNameChkTick_ := GetTickCount;
try
var sInfo: String := GetEmpNoInfo(DestServerUrl, HTTP_, sEmpNo_);
if sInfo <> '' then
begin
var OInfo: ISuperObject := SO(sInfo);
sUName_ := OInfo.S['name'];
end;
except
//
end;
end;
end;
end;
O.S['mwPKey_ISOSPATCHSELECT'] := O.S['mwPKey_BLOCKPENDING'];
// O.S['mwPKey_OPTIONH'] := O.S['mwPKey_BLOCKPORT'];
// O.S['mwPKey_BLOCKPORT'] := 'false';
// O.Delete('mwPKey_BLOCKPENDING');
if AgentModel_.Location <> O.S['mwPKey_LOCNAME'] then
begin
AgentModel_.Location := O.S['mwPKey_LOCNAME'];
AgentModel_.Save;
_Trace('그룹 정책 변경됨', 1);
end;
if ((AgentModel_.IP = '') or (AgentModel_.IP = IP_NULL)) and
((sIp <> '') and (sIp <> IP_NULL)) then
begin
AgentModel_.IP := sIp;
AgentModel_.MAC := sMac;
if IsUseHostNameOnly then
AgentModel_.HostName := sComName_
else
AgentModel_.HostName := sUserName_;
if AgentModel_.FirstConn then
begin
SendEventLog(URI_CONNECT, SYSEVT_AGENT_INSTALL, 'Agent first connected');
AgentModel_.FirstConn := false;
end;
AgentModel_.Save;
end;
try
// 전역 포트 블럭으로 사용동의서 가져오기 전에 짤릴 수 있어서 미리 받아놓는다 22_0503 10:02:52 kku
if (sEulaContent_ = '') and (AgentModel_.AgentId <> '') then
begin
var sDest: String := StringReplace(sDestSvrUrl_, 'agentLogRequest.do', 'agentEulaContent', [rfReplaceAll]);
sDest := StringReplace(sDest, 'agentLogRequests.do', 'agentEulaContent', [rfReplaceAll]);
sDest := sDest + '/' + AgentModel_.AgentId;
// sDest := 'https://192.168.14.125:8443/agentEulaContent/김진아';
sEulaContent_ := HTTP_.Get(sDest);
// 보안서약서 비어 있는지 체크 22_0727 16:19:51 kku
if (sEulaContent_ <> '') and not sEulaContent_.EndsWith('null}') then
begin
if AgentModel_.EulaTxt <> sEulaContent_ then
begin
AgentModel_.EulaTxt := sEulaContent_;
AgentModel_.Save;
end;
end else
sEulaContent_ := '';
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetEulaContent ..');
end;
{$IFNDEF DEBUG}
if not bRcvRemoveAgent_ and (Trim(O.S['KEY_FORCEUNINSTALL']).ToLower = 'true') then
begin
_Trace('Req .. AgentUninstall ..');
bRcvRemoveAgent_ := true;
SendEventLog(URI_USER_ACTION, SYSEVT_REQ_AGENT_UNINSTALL, '[Req] Uninstall Agent');
if hRcvHwnd_ <> 0 then
PostMessage(hRcvHwnd_, WM_REQ_AGENT_UNINSTALL, 0, 0);
end;
{$ENDIF}
sScanPolicy := O.S['KEY_SCANSCHEDULE'];
O.S['KEY_SCANSCHEDULE'] := '';
sDirCollect := O.S['KEY_DIRCOLLECT'];
O.S['KEY_DIRCOLLECT'] := '';
if bChangeAgentInfo then
AgentInfo := NewAgentInfo;
sLastPolicy_ := O.S['KEY_LASTPOLICY'];
bChangedPolicy := PrefModel.SetPrefModel(O);
if bChangedPolicy then
begin
if PrefModel_.IdlPolicy <> '' then
begin
try
OSub := SO(PrefModel_.IdlPolicy);
PrefIdlModel_.SetPrefModel(OSub);
except
_Trace('Invalid SubPolicyData ... 1');
end;
end else
if PrefIdlModel_.Loaded then
PrefIdlModel_.Clear;
if PrefModel_.VulPolicy <> '' then
begin
try
OSub := SO(PrefModel_.VulPolicy);
PrefVulModel_.SetPrefModel(OSub);
except
_Trace('Invalid SubPolicyData ... 2');
end;
end else
if PrefVulModel_.Loaded then
PrefVulModel_.Clear;
if PrefModel_.OffPolicy <> '' then
begin
try
OSub := SO(PrefModel_.OffPolicy);
PrefOffline_.SetPrefModel(OSub);
except
_Trace('Invalid SubPolicyData ... 3');
end;
end else
if PrefOffline_.Loaded then
PrefOffline_.Clear;
// if PrefModel_.ExpPolicy <> '' then
// begin
// try
// OSub := SO(PrefModel_.ExpPolicy);
// PrefExpPolicy_.SetPrefModel(OSub);
// except
// _Trace('Invalid SubPolicyData ... 4');
// end;
// end else
// if PrefExpPolicy_.Loaded then
// PrefExpPolicy_.Clear;
if PrefModel.VpnAppName <> sVpnClient_ then
sVpnClient_ := PrefModel.VpnAppName;
_Trace('정책 업데이트 완료', 1);
end;
sAgentPatchVersion_ := PrefModel.AgentPatchVersion;
LB_ProcessPolicy :
//// if IsCheckExpireDate then // 전체 업체에서 사용가능 하도록 확대 22_0803 12:56:03 kku
// begin
// // 보안모드 진입 시 날짜 제한 체크
// try
// if (PrefModel.RestricDate <> '') then
// begin
// var dt: TDateTime := AppendTime(TDate(ConvStrToDateTime(PrefModel.RestricDate)), 23, 59, 59, 0);
// bIsRestricDate_ := (dt <> 0) and (CompareDateTime(dt, Now) = -1);
// if bIsRestricDate_ then
// PrefModel.IsAllowAccess := false;
// end else
// bIsRestricDate_ := false;
// except
// on E: Exception do
// ETgException.TraceException(Self, E, 'Fail .. IsCheckExpireDate()');
// end;
// end;
// 네트워크 카드 내렸다 올렸을때 정책 다시 받아오면서
// PrefModel.IsOsPatchCheck = false로 바뀌는 바람에 초기화 되는 현상 있음 22_0614 09:37:37 kku
// if IsOsPatchCheckWeek then
// begin
// if not PrefModel.IsOsPatchCheck and (AgentModel_.LastOsPatchDT <> 0) then
// begin
// // OS 패치 확인 Off되면 초기화
// AgentModel_.LastOsPatchDT := 0;
// AgentModel_.Save;
// end;
// end;
UpdateInternalInfo;
// if IsUseAfterReport and PrefModel.IsUseAfterReport then
if PrefModel.IsUseAfterReport then
begin
if AgentModel_.AfterRptDT <> 0 then
PopupAfterReport;
end;
// 보안 정책 활성화
// TimerCheckServiceAvailable()로 이동 23_0322 08:01:57 kku
// UpdatePolicyActive(ModePolicy);
if UpdateTick <> 0 then
begin
// 10분간 업데이트 시도가 끝나지 않으면
// 다시 시도 하기 위해 초기화 해준다 23_0830 13:41:36 kku
if (GetTickCount - UpdateTick) >= 600000 then
UpdateTick := 0;
end;
if (UpdateTick = 0) and (sAgentPatchVersion_ <> '') and
CheckUpdateAble(sAgentPatchVersion_, SdkVersion) then
begin
ProcessUpdate(sAgentPatchVersion_);
end else begin
ProcessCttSchSchedule(sScanPolicy);
ProcessCltFldSchedule;
end;
// ProcessCttSchSchedule('scanid:kuedcebztckkbblkkkzt|scandate:2022-08-10 09:14:27|scantype:part|scanoption:1056002;1056006;1057010;');
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerProcessStatus()');
end;
end;
procedure TManagerService.TimerCheckOsConfig(aSender: TObject);
procedure ProcessIdleLock;
var
LastInput: TLastInputInfo;
dwTick: DWORD;
begin
if ( (PrefModel.ForceScreenLockMin > 0) or PrefModel.IsForceShutdown or ModePolicy.UseIdleScrLogoBold or
(VulService_.IsVpnOn and PrefModel.IsUnsafeActions) ) then
begin
ZeroMemory(@LastInput, SizeOf(LastInput));
LastInput.cbSize := SizeOf(LastInput);
if GetLastInputInfo(LastInput) then
begin
if LastInput.dwTime = 0 then
_Trace('??? LastInput = 0 .. 1');
dwTick := GetTickCount;
if (PrefModel.ForceScreenLockMin > 0) and
((dwTick - LastInput.dwTime) > (PrefModel.ForceScreenLockMin * 60000)) then
begin
case PrefModel.ScreenLockKind of
slkCustom,
slkBoth :
begin
if (hRcvHwnd_ <> 0) and (FindWindow('TDlgLockScreen', nil) = 0) then
SendMessage(hRcvHwnd_, WM_SCREENLOCK, 0, 0);
end;
end;
case PrefModel.ScreenLockKind of
slkDef,
slkBoth :
begin
var h: HWND := GetForegroundWindow;
if h <> 0 then
SendMessage(h, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
end;
end;
end;
if (ModePolicy.ScreenLogo <> askNone) and ModePolicy.UseIdleScrLogoBold and
((dwTick - LastInput.dwTime) > (ModePolicy.MinIdleScrLogoBold * 60000)) then
begin
bIsIdleScreenLogo_ := true;
end else
if bIsIdleScreenLogo_ then
bIsIdleScreenLogo_ := false;
if PrefModel.IsForceShutdown and (PrefModel.ForceShutdownMin > 0) and
((dwTick - LastInput.dwTime) > (PrefModel.ForceShutdownMin * 60000)) then
begin
// 다시 시도 안하게 조치 부터 함.
PrefModel.ForceShutdownMin := 0;
DirectSendEventLog(URI_USER_ACTION, SYSEVT_SHUTDOWN, 'System Shutdown');
if CUSTOMER_TYPE = CUSTOMER_DEV then
ExecutePath('shutdown', '/f /r /t 0') // 원격에서 테스트를 위함 23_0206 16:55:55 kku
else
ExecutePath('shutdown', '/f /s /t 0');
end
end;
end;
end;
var
nScreenTime,
nScreenSecure,
nScreenSaverActive: Integer;
bEmptyPass,
bPassTermOk: Boolean;
dwTick: DWORD;
sCurAccount,
sUserName: String;
bCheckPW: Boolean;
begin
//exit;
try
// if (gClient <> nil) and gClient.Connected then
// begin
// // 5분에 한번 태그 정보 저장 23_0220 11:24:17 kku
// dwTick := GetTickCount;
// if (dwSLSaveTick_ = 0) or ((dwTick - dwSLSaveTick_) > 300000) then
// begin
// dwSLSaveTick_ := dwTick;
// gClient.SendPacket(TTgPacket.Create(SLC_REQUEST_SAVEDATA));
// end;
// end;
// 신한카드 safePC 설치 체크, 삭제 (나중에 제거해야함 23_0109 14:57:22 kku)
if CUSTOMER_TYPE = CUSTOMER_SHCD then
begin
// 5분에 한번
dwTick := GetTickCount;
if (dwTick - dwCheckSafePC_) > 300000 then
begin
dwCheckSafePC_ := dwTick;
var sSafePcUninst := GetRunExePathDir + EXE_SafePCUninst;
if FileExists(sSafePcUninst) then
begin
var sNicDir: String := GetWindowsDir + 'Nics\';
if FileExists(sNicDir + 'SMSS.exe') and
FileExists(sNicDir + 'Client.exe') and
FileExists(sNicDir + 'spe.exe') then
begin
_Trace('safePC Found .. Run Uninst.');
ExecuteAppWaitUntilTerminate(sSafePcUninst, '', SW_HIDE, 10000);
if not FileExists(sNicDir + 'SMSS.exe') or
not FileExists(sNicDir + 'Client.exe') or
not FileExists(sNicDir + 'spe.exe') then
begin
_Trace('safePC Delete .. Delete Uninst.');
DeleteFile(PChar(sSafePcUninst));
end;
end else begin
_Trace('safePC Not Found .. Delete Uninst.');
DeleteFile(PChar(sSafePcUninst));
end;
end;
end;
end;
if bTerminateThdScanSch_ then
begin
bTerminateThdScanSch_ := false;
if ThdScanSch_ <> nil then
FreeAndNil(ThdScanSch_);
end;
if NicService_ <> nil then
NicService_.UpdateNic;
// SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, @nScreenSaverActive, 0);
if IsSkipScreenSaver or not PrefModel_.VulScreenSaver or not PrefModel_.IsEnableCheck then
nScreenSecure := 1
else
SystemParametersInfo(SPI_GETSCREENSAVESECURE, 0, @nScreenSecure, 0);
// SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, @nScreenTime, 0);
CheckHostAndUserInfo;
bEmptyPass := false;
bPassTermOk := true;
sUserName := ExtractFileName(sDomain_); // 변경전 최초 이름?
bCheckPW := false;
// 로그인, 로그아웃 확인을 위해 로그온 시간변경 탐지를 위로 올림 24_0207 17:12:19 kku
// 마지막 로그온 시간 변경될때만 비밀번호 점검하도록 보완 24_0109 13:26:27 kku
if dtLastLogOn_ = 0 then
begin
dtLastLogOn_ := GetLastLogOnDT(sComName_, sUserName);
if dtLastLogOn_ <> 0 then
begin
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'LLO', IntToStr(DelphiToJavaDateTime(dtLastLogOn_)), true);
bCheckPW := true;
end;
end else begin
var dtLLO: TDateTIme;
var nBadCnt: Integer;
if GetLastLogOnDTandBadCnt(sComName_, sUserName, dtLLO, nBadCnt) then
begin
bCheckPW := nBadCnt = 0;
if dtLLO <> dtLastLogOn_ then
begin
_Trace('로그온 시간변경 감지, Old=%s, New=%s', [DateTimeToStr(dtLastLogOn_), DateTimeToStr(dtLLO)], 2);
// 사용자가 변경되었는지 확인한다 24_0207 17:13:09 kku
sCurAccount := WTS_GetCurrentUserName;
if sAccount_ <> sCurAccount then
begin
_Trace('사용자 변경 감지, Old=%s, New=%s', [sAccount_, sCurAccount], 2);
if sCurAccount <> '' then
begin
sDomain_ := '';
sAccount_ := '';
sUserName_ := '';
CheckHostAndUserInfo;
end;
end;
// 로그온 시간이 달라졌다는건 로그온을 했거나 잠금해제를 했거나 비번 변경 했을때이다.
// 비번 체크 다시 해준다.
dtLastLogOn_ := dtLLO;
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'LLO', IntToStr(DelphiToJavaDateTime(dtLastLogOn_)), true);
bCheckPW := true;
end;
end else begin
// _Trace('Fail .. GetLastLogOnDTandBadCnt()', 2);
end;
end;
if IsSkipPwd or not PrefModel_.VulPassword or not PrefModel_.IsEnableCheck then
begin
// bEmptyPass := false;
end else begin
if bCheckPW then
begin
bEmptyPass := not HasAccountPassword(sComName_, sUserName);
// _Trace('비밀번호 취약 점검 .. Empty : %s', [BooleanToStr(bEmptyPass, 'Yes', 'No')], 2);
end;
if (PrefModel_.PwChkTerm <> pctNone) and
(PrefModel_.PwChkTermDay > 0) and (sComName_ <> '') then
begin
dtLastChangePW_ := GetLastChangePasswordDT(sComName_, sUserName);
if dtLastChangePW_ <> 0 then
bPassTermOk := DaysBetween(Now, dtLastChangePW_) < PrefModel_.PwChkTermDay;
end;
end;
if HandleConfig_ <> nil then
HandleConfig_.Update(nScreenSecure = 1, not bEmptyPass, bPassTermOk, sUserName_);
ProcessIdleLock;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. TimerCheckOsConfig()');
end;
end;
{
procedure TManagerService.TimerCheckConnect(aSender: TObject);
var
bConnected,
bPrevConnected: Boolean;
// sDestUrl: String;
begin
try
bConnected := HttpPost(sDestSvrUrl_, '123000', JSON_CONNCHECK) <> '';
bPrevConnected := GetConnected;
if not bConnected then
begin
if not bPrevConnected then
begin
if bFailChangeDestUrl then
ChangeDestinationUrl
end else
SetConnected(false, false);
end else
if not bPrevConnected then
SetConnected(true, false);
if bConnected then
begin
if VulService_.IsVpnOn and bDoEmpNoCheck_ then
begin
// 사번검증을 통해 미검증 시 보안모드 진입을 막을 예정이었으나...
// 일단 그렇게까지 동작하지 않도록 함 22_0531 16:04:58 kku
bIsEmpNoOk_ := VerifyEmpNo(DestServerUrl, HTTP_, sEmpNo_);
bDoEmpNoCheck_ := false;
if not bIsEmpNoOk_ then
begin
PopupMessage(TYPE_MSG_VUL_EMPNO);
if CUSTOMER_TYPE = CUSTOMER_KFTC then
begin
// 금융결제원의 경우 사번이 유효하지 않은 경우 (인사연동 안된 사번)
// 보안모드 차단 되도록 기능 추가 23_0425 12:52:05 kku
VulService_.SetDisconnect(true);
end;
end;
end else
bIsEmpNoOk_ := true;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerCheckConnect()');
end;
end;
}
procedure TManagerService.TimerCheckServiceAvailable(aSender: TObject);
function IsServiceProcessAvailable: Boolean;
var
sVpnClient: String;
i: Integer;
ProcList: TStringList;
begin
Result := false;
try
sVpnClient := sVpnClient_;
if sVpnClient = '' then
exit;
if _CheckVpnProcs <> sVpnClient then
begin
_CheckVpnProcs := sVpnClient;
SplitString(_CheckVpnProcs, ';', _CheckVpnList);
end;
Guard(ProcList, TStringList.Create);
ProcList.CaseSensitive := false;
if GetProcessNameToList(ProcList) > 0 then
begin
for i := 0 to _CheckVpnList.Count - 1 do
if ProcList.IndexOf(_CheckVpnList[i]) <> -1 then
begin
bIsVpnClientON_ := true;
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsServiceProcessAvailable()');
end;
end;
function IsRemoteProcessAvailable: Boolean;
var
sList,
sCuUrl: String;
i, n: Integer;
Label
LB_GetNextHwnd;
begin
Result := false;
sList := PrefModel.VpnRcAppList;
if sList.Contains('zo') and (GetProcessPidsByName('cpthost.exe') > 0) then
Exit(true);
if sList.Contains('we') and
( (GetProcessPidsByName('ebexmta.exe') > 0) or
(GetProcessPidsByName('webexmta.exe') > 0) ) then
Exit(true);
if sList.Contains('wh') and (GetProcessPidsByName('whale.exe') > 0) then
begin
// 웨일온 화상회의 인식 보완 22_0809 15:07:23 kku
var pRoleStr: TBytes;
SetLength(pRoleStr, 300);
var h := FindWindow('Chrome_WidgetWin_1', nil);
var sClassName: String;
var ProcEnumAccessible: TProcessEnumAccessible;
var bResult := false;
while h <> 0 do
begin
ProcEnumAccessible :=
procedure(aParentAccObj, aAccObj: IAccessible; varChild: OleVariant; h: HWND; nLevel: Integer; var bContinue: Boolean)
var
sName,
sRole: String;
begin
bContinue := false;
try
if Assigned(aAccObj) then
begin
sName := Trim(LowerCase(GetObjectName(aAccObj, varChild)));
sRole := '';
ZeroMemory(pRoleStr, 300);
if GetObjectRoleString(aAccObj, varChild, @pRoleStr[0]) then
sRole := DeleteNullTail(String(@pRoleStr[0]));
if not VarIsNull(varChild) and
(Pos(sName, '회의 정보') > 0) then
begin
bResult := true;
bContinue := false;
end else
bContinue := true;
end;
except
// ..
end;
end;
EnumAccessible(h, ProcEnumAccessible);
if bResult then
Exit(true);
LB_GetNextHwnd :
h := GetWindow(h, GW_HWNDNEXT);
if h = 0 then
break;
sClassName := GetWndClassName(h);
if sClassName <> 'Chrome_WidgetWin_1' then
goto LB_GetNextHwnd;
end;
end;
if sList.Contains('cu') then
begin
if GetProcessPidsByName('cmconf.exe') > 0 then
Exit(true);
// 사용하지 않음... 나중에 사용 이슈 발생 시 재활성? 25_0513 15:23:13 kku
sCuUrl := '';// GetCurBrowserUrl(AccObj_SubTitle_, varSubTitle_, hEditWnd_);
if (sCuUrl <> '') and (Pos('uprism.io/room', sCuUrl) > 0) then
begin
Exit(true);
end else
if AccObj_SubTitle_ <> nil then
begin
AccObj_SubTitle_ := nil;
VariantClear(varSubTitle_);
hEditWnd_ := 0;
end;
end;
end;
function IsNexgClientRun: Boolean;
const
REGKEY_NEXG = 'SOFTWARE\SoftEther Project\SecurityCenter2\sevpnsecure';
ENCKEY_NEXG: AnsiString = 'nexg6sslvpn201';
function DecryptEmpNo(sEncStr: String): AnsiString;
var
pKeyBuf,
pSrcBuf, pDecBuf: TBytes;
nLen: Integer;
ACtx: TAESContext;
ABlk: TAESBlock;
begin
Result := '';
if sEncStr = '' then
exit;
SetLength(pKeyBuf, 32);
FillChar(pKeyBuf[0], 32, #0);
CopyMemory(pKeyBuf, @ENCKEY_NEXG[1], Length(ENCKEY_NEXG));
nLen := ConvStrToBin(sEncStr, pSrcBuf);
ASSERT(nLen > 0);
ZeroMemory(@ACtx, SizeOf(ACtx));
ZeroMemory(@ABlk, SizeOf(ABlk));
// CopyMemory(@ABlk, pKeyBuf, AESBLKSIZE);
if AES_CBC_Init_Decr(pKeyBuf[0], 256, ABlk, ACtx) <> 0 then
begin
exit;
end;
SetLength(pDecBuf, nLen);
if AES_CBC_Decrypt(@pSrcBuf[0], @pDecBuf[0], nLen, ACtx) <> 0 then
begin
exit;
end;
SetLength(Result, nLen);
CopyMemory(@Result[1], @pDecBuf[0], nLen);
Result := DeleteNullTail(Result);
end;
var
sEncUser: String;
begin
Result := false;
sEncUser := GetRegValueAsString(HKEY_LOCAL_MACHINE, REGKEY_NEXG, 'vpn_conneted_user');
if sEncUser = '' then
exit;
Result := DecryptEmpNo(sEncUser) = sEmpNo_;
// if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REGKEY_NEXG, 'VPN_status') = 1 then
// Exit(true);
end;
function ServAvailable: Boolean;
var
bRes, bIsVpnAnd, bIsVpnApp,
bIsVpnNic, bIsVpnAlways,
bIsVpnRc, bIsVpnIp, bIsVpnHour, bIsNac: Boolean;
sTemp: String;
ResList: TList<Boolean>;
i: Integer;
bExitImpossible: Boolean;
begin
Result := false;
// if IsRestricMac then
// begin
// if bIsServiceAvailable_ and (VulService_ <> nil) then
// VulService_.SetDisconnect(true, true);
//
// exit;
// end;
//
// if IsRestricDate then
// begin
// if bIsServiceAvailable_ and (VulService_ <> nil) then
// VulService_.SetDisconnect(true, true);
//
// exit;
// end;
// "보안모드 허용" 정책 의미 변경
// 보안모드를 차단 하고 "보안모드 종료시 동작"으로 되도록 조치 23_0614 15:02:57 kku
// case CUSTOMER_TYPE of
// CUSTOMER_JB_DEV,
// CUSTOMER_JB_MAINTAIN : ;
// else begin
// if not PrefModel.IsAllowAccess then
// exit;
// end;
// end;
sTemp := PrefModel.VpnMethod;
bIsVpnAnd := PrefModel.IsVpnAndCondition;
bIsVpnApp := sTemp.Contains('app');
bIsVpnIp := sTemp.Contains('ip');
bIsVpnRc := sTemp.Contains('rc');
bIsVpnNic := sTemp.Contains('nic');
bIsVpnAlways := sTemp.Contains('time');
// if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REG_HE, 'LOC') = 1 then
// _Trace('항상 옵션 = %s', [BooleanToStr(bIsVpnAlways, 'Yes', 'No')]);
bIsVpnHour := sTemp.Contains('hour');
bIsNac := sTemp.Contains('et');
bExitImpossible := false;
Guard(ResList, TList<Boolean>.Create);
if bIsVpnApp then
begin
if IsServiceProcessAvailable then
begin
// _Trace('IsApp - ON');
ResList.Add(true);
bExitImpossible := not PrefModel_.IsSecuEndActions or not PrefModel.UnsafeActions.Contains('app');
end else
ResList.Add(false);
end;
if bIsVpnIp then
begin
if IsRouterOn then
begin
// _Trace('IsVpnIp - ON');
ResList.Add(true);
bExitImpossible := not PrefModel_.IsSecuEndActions or not PrefModel_.UnsafeActions.Contains('net');
end else
ResList.Add(false);
end;
if bIsVpnNic then
begin
if IsVpnNicOn then
begin
ResList.Add(true);
// _Trace('IsVpnNic - ON');
bExitImpossible := not PrefModel_.IsSecuEndActions or not PrefModel_.UnsafeActions.Contains('vnic');
// bIsSafeExitImpossible_ := bIsSafeExitImpossible_ or
// (not PrefModel.UnsafeActions.Contains('vnic') and
// not PrefModel.UnsafeActions.Contains('net'));
end else
ResList.Add(false);
end;
if bIsVpnRc then
begin
if IsRemoteProcessAvailable then
begin
ResList.Add(true);
// _Trace('IsVpnRc - ON');
end else
ResList.Add(false);
end;
if IsUseNexgClient then
ResList.Add(IsNexgClientRun);
if bIsVpnAlways then
begin
// 업무시간에서 항상으로 변경됨 22_0615 09:54:54 kku
// _Trace('IsVpnAlways - ON');
ResList.Add(true);
bExitImpossible := true;
// if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REG_HE, 'LOC') = 1 then
// _Trace('항상 옵션 조건 OK');
end;
if bIsVpnHour then
begin
sTemp := PrefModel.VpnHour;
var nPos: Integer := Pos(';', sTemp);
if nPos > 0 then
begin
var nB: Integer := StrToIntDef(Copy(sTemp, 1, nPos - 1), -1);
Delete(sTemp, 1, nPos);
var nE: Integer := StrToIntDef(sTemp, -1);
if (nB <> -1) and (nE <> -1) and (nB <= nE) then
begin
var wHour, wMin, wSec, wMSec: WORD;
DecodeTime(Now, wHour, wMin, wSec, wMSec);
if (nB <= wHour) and (nE >= wHour) then
begin
// _Trace('IsVpnHour - ON');
ResList.Add(true);
bExitImpossible := true;
end else
ResList.Add(false);
end;
end;
end;
// NAC 접속 체크 추가 23_0517 15:12:51 kku
if bIsNac then
begin
if (dtSvrDisconn_ <> 0) and
(SecondsBetween(Now, dtSvrDisconn_) > 5) then
begin
if Pos('VPN:', NicService_.IpAll) > 0 then
bPreNacChk_ := true
else
if (PrefModel_.NacCheckUrl <> '') and
(dwNacChkTick_ = 0) or ((GetTickCount - dwNacChkTick_) > 20000) then
begin
dwNacChkTick_ := GetTickCount;
bRes := IsUrlValid(PrefModel_.NacCheckUrl, 3000);
if NicService_.IsActiveAP then // AP 활성화 상태일때만 적용
bPreNacChk_ := bRes;
end;
end else
if bPreNacChk_ then
bPreNacChk_ := false;
ResList.Add(bPreNacChk_);
end else
if bPreNacChk_ then
bPreNacChk_ := false;
if ResList.Count = 0 then
begin
// _Trace('NoCheckSecuMode');
if IsVpnNetworkcardCheck or IsVpnIpCheck then
begin
if IsVpnAppCheck then
begin
bRes := IsRouterOn and IsServiceProcessAvailable;
end else begin
if IsRouterOn then
bRes := true
else
bRes := IsServiceProcessAvailable;
end;
end else
if IsVpnAppCheck then
bRes := IsServiceProcessAvailable;
end else begin
// _Trace('CheckSecuMode');
if bIsVpnAnd then
begin
bRes := true;
for i := 0 to ResList.Count - 1 do
if not ResList[i] then
begin
bRes := false;
break;
end;
end else begin
bRes := false;
for i := 0 to ResList.Count - 1 do
if ResList[i] then
begin
bRes := true;
break;
end;
end;
end;
// if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REG_HE, 'LOC') = 1 then
// _Trace('보안모드 판단 결과 = %s', [BooleanToStr(bRes, 'Yes', 'No')]);
if bRes then
begin
if not VulService_.IsVpnOn and
( not VulService_.IsSafeMode or
not VulService_.IsWhiteApp or
(not VulService_.IsOsPatchUptoDate and (PrefModel.OsPatchCheck = opcCheck)) or
(not VulService_.IsSafePersonalInfo and PrefModel.IsScanBlock) or
(not VulService_.IsPasswordSetTermOk and (PrefModel.PwChkTerm = pctBlock))
) then
begin
// 취약 상태라면
if PrefModel.IsAllowAccess and // 접속 승인 상태 확인 추가 22_0602 14:22:42 kku
PrefModel.IsTemporaryConn and not IsTemporaryConn then
begin
// 임시 연결 정책 확인해서 처리
// todo : 임시 연결 타이머 처리 kku
SetTemporaryConn(true);
VulService_.SetUseTempConn(true);
end;
end;
if dwSecuExitWaitTick_ <> 0 then
dwSecuExitWaitTick_ := 0;
Result := true;
end else
Result := false;
// 보안모드 해제 대기 추가 23_1107 15:59:36 kku
if bIsServiceAvailable_ and not Result and
(PrefModel_.SecuExitWaitSec > 0) then
begin
if dwSecuExitWaitTick_ = 0 then
begin
Result := true;
dwSecuExitWaitTick_ := GetTickCount;
exit;
end;
if (GetTickCount - dwSecuExitWaitTick_) < (PrefModel_.SecuExitWaitSec * 1000) then
begin
Result := true;
exit;
end;
end;
bIsSafeExitImpossible_ := Result and bExitImpossible;
UpdatePolicyActive(ModePolicy);
// if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REG_HE, 'LOC') = 1 then
// _Trace('보안모드 판단 결과2 = %s', [BooleanToStr(bRes, 'Yes', 'No')]);
end;
var
sDest: String;
begin
//exit;
try
SetServiceAvailable(ServAvailable);
// if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REG_HE, 'LOC') = 1 then
// SetRegValueInteger(HKEY_LOCAL_MACHINE, REG_HE, 'LOC', 0);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerCheckServiceAvailable()');
end;
end;
procedure TManagerService.TimerCheckTemporaryConn(aSender: TObject);
begin
//exit;
try
if IsTemporaryConn then
begin
// 임시 보안모드 사용중일때 시간 체크 22_0425 10:46:23 kku
if ((GetTickCount - dwTempConnBegin_) > (PrefModel.TemporaryConnMin * 60000)) or
not PrefModel.IsTemporaryConn then
begin
VulService_.TryExitSafeMode(true);
if IsSafeExitImpossible then
SetTemporaryConn(false);
end else
if VulService_.IsSafeMode and VulService_.IsWhiteApp and
(VulService_.IsOsPatchUptoDate or (PrefModel.OsPatchCheck <> opcCheck)) and
(VulService_.IsSafePersonalInfo or not PrefModel.IsScanBlock) and
(VulService_.IsPasswordSetTermOk or not (PrefModel.PwChkTerm = pctBlock)) then
begin
// 다시 안전모드 체크해서 임시 보안모드 끝내기 22_0613 13:56:17 kku
SetTemporaryConn(false);
// 10분씩 연장해서 사용...? 악용될 소지가 있다... 22_0613 14:07:01 kku
VulService_.SetUseTempConn(false);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerCheckTemporaryConn()')
end;
end;
procedure TManagerService.TimerCheckConnect(aSender: TObject);
var
dwTick: DWORD;
sRes: String;
O: ISuperObject;
bIsConn: Boolean;
begin
try
if nChkConnSec_ <> PrefModel_.ChkConSec then
nChkConnSec_ := PrefModel_.ChkConSec;
if nChkConnSec_ < 0 then
exit;
bIsConn := false;
dwTick := GetTickCount;
if (dwTick > dwTickChkConn_) and
((dwTick - dwTickChkConn_) > (nChkConnSec_ * 1000)) then
begin
dwTickChkConn_ := dwTick;
sRes := HTTP_.Get(sDestIPort_ + 'aapi/ping');
if sRes <> '' then
begin
try
O := SO(sRes);
bIsConn := O.S['msg'] = 'pong';
except
on E: Exception do
ETgException.TraceException(Self, E, Format('Fail .. TimerCheckConnect() .. invalid json=%s', [sRes]), 10);
end;
end;
if bIsConn <> bIsConnected_ then
SetConnected(bIsConn, bIsNewApi_);
end;
except
on E: EIdSocketError do
begin
if bIsConn <> bIsConnected_ then
SetConnected(bIsConn, bIsNewApi_);
end;
on E: EIdHTTPProtocolException do
begin
if E.ErrorCode = 302 then
begin
// 서버에서 지원하지 않는 경우 패스
ThdStatusTimer_.AddTask(TimerCheckConnect, 1000, false, false);
exit;
end;
end;
on E: Exception do
begin
// 실패하면 60초뒤 다시 시도 25_0819 10:56:34 kku >> 안함
// dwTickChkConn_ := dwTick + 60000;
ETgException.TraceException(Self, E, 'Fail .. TimerCheckConnect()', 9);
end;
end;
end;
procedure TManagerService.TimerProcessStatus(aSender: TObject);
begin
//exit;
//{$IFDEF DEBUG} // TEST_KJ
// ProcessCampaign;
//exit;
//{$ENDIF}
if IsNewServerOnly then
begin
if not bIsNewApi_ then
bIsNewApi_ := true;
ProcessSignal;
ProcessCampaign;
ProcessCheck_xPrintData(HTTP_);
end else
if IsOldServerOnly then
begin
if bIsNewApi_ then
bIsNewApi_ := false;
ProcessStatusOld;
end else begin
if not GetConnected then
begin
ProcessSignal(false);
if not GetConnected then
begin
ProcessStatusOld(false);
if not GetConnected then
ChangeDestinationUrl;
end;
end else
if bIsNewApi_ then
begin
ProcessSignal;
ProcessCampaign;
end else
ProcessStatusOld;
end;
if (PrefModel_.HealthCheckMilSec >= 1000) and
(PrefModel_.HealthCheckMilSec <> dwStatusInterval_) then
begin
dwStatusInterval_ := PrefModel_.HealthCheckMilSec;
ThdStatusTimer_.SetTask(TimerProcessStatus, dwStatusInterval_, true);
SendEventLogEx(SYSEVT_HEALTHCHECK_PERIOD, Format('HealthCheckTerm=%d', [dwStatusInterval_]), false);
_Trace('통신 주기 변경 : %d초', [dwStatusInterval_ div 1000], 1);
end;
//{$IFDEF DEBUG}
// ProcessSignal;
// ProcessCampaign;
//{$ELSE}
// ProcessStatusOld;
//{$ENDIF}
end;
procedure TManagerService.TimerCheckSecurity(aSender: TObject);
var
PidList: TProcessIdList;
i: Integer;
dwSsid: DWORD;
PdList: TWSCProductEntList;
begin
//exit;
try
CheckEmpNo_TMAP;
if MgPrint_ <> nil then
MgPrint_.ProcessExpired;
// if CUSTOMER_TYPE = CUSTOMER_KBIZ then
// ExcelCheckAndHideRun(RecentUserSid);
// RDP 상태 체크 추가 23_0926 08:56:24 kku
Guard(PidList, TProcessIdList.Create);
if GetProcessPidsByName('winlogon.exe', PidList) > 1 then
begin
for i := 0 to PidList.Count - 1 do
begin
dwSsid := 0;
if ProcessIdToSessionId(PidList[i], dwSsid) and (dwSsid <> 0) then
begin
if WTS_GetUserNameFromSessionID(dwSsid) = '' then
begin
// 계정 이름이 비어있는게 있다면 원격접속 된거라고 판단 23_0926 09:02:07 kku
if not bIsRdpLogon_ then
begin
bIsRdpLogon_ := true;
// 원격접속 하면
UpdateScreenLogo(true);
end else begin
try
if (Screen.Width <> nRdpW_) or (Screen.Height <> nRdpH_) then
begin
_Trace('ChageDisplay .. RDP .. OldW=%d, OldH=%d, NewW=%d, NewH=%d',
[nRdpW_, nRdpH_, Screen.Width, Screen.Height], 1);
nRdpW_ := Screen.Width;
nRdpH_ := Screen.Height;
UpdateScreenLogo(true);
end;
except
_Trace('Fail .. RDP .. CheckAnd UpdateScreenLogo()', 1);
end;
end;
if not bIsRdpLogonScreenLogo_ and GetModePolicy.UseRemoteScrLogoBold then
bIsRdpLogonScreenLogo_ := true;
break;
end;
end;
end;
end else
if bIsRdpLogon_ then
begin
bIsRdpLogon_ := false;
bIsRdpLogonScreenLogo_ := false;
nRdpW_ := 0;
nRdpH_ := 0;
end;
case CUSTOMER_TYPE of
CUSTOMER_KFTC :
begin
if GetProcessPidByName(EXE_KF) = 0 then
begin
var sDir: String := GetRunExePathDir + DIR_CONF;
var sPath: String := sDir + EXE_KF;
if not FileExists(sPath) then
begin
CopyFile(PChar(sDir + EXE_IC), PChar(sDir + EXE_KF), false);
Sleep(500);
end;
ExecutePath_hide(sPath);
end;
end;
// CUSTOMER_LSITC :
// begin
// var sTemp: String := GetRegValueAsString(HKEY_USERS, RecentUserSid + '\Control Panel\Desktop', 'SCRNSAVE.EXE');
// if CompareText(ExtractFileName(sTemp), 'LSITC_Scr.scr') <> 0 then
// begin
// var sScrPath: String := GetRunExePathDir + DIR_CONF + 'LS1.dat';
// if FileExists(sScrPath) then
// begin
// var sDestPath: String := GetWindowsDir;
// if Length(sDestPath) > 0 then
// begin
// {$IFDEF WIN64}
// sDestPath := sDestPath[1] + ':\Windows\SysWOW64\LSITC_Scr.scr';
// {$ELSE}
// sDestPath := GetSystemDir + 'LSITC_toScr.scr';
// {$ENDIF}
// SetRegValueString(HKEY_USERS, RecentUserSid + '\Control Panel\Desktop', 'toBkSCRNSAVE.EXE', sTemp, true);
// CopyFile(PChar(sScrPath), PChar(sDestPath), false);
// SetRegValueString(HKEY_USERS, RecentUserSid + '\Control Panel\Desktop', 'SCRNSAVE.EXE', sDestPath, true);
// end;
// end;
// end;
// end;
end;
if PrefModel_.IsEnableCheck and
(PrefModel_.VulAntiVirus or PrefModel_.VulFirewall) then
begin
Guard(PdList, TWSCProductEntList.Create);
if PrefModel_.VulFirewall then
begin
if (GetWscSecurityInfo(WSC_SECURITY_PROVIDER_FIREWALL, PdList) > 0) and (HandleSecurity_ <> nil) then
HandleSecurity_.Update(PdList);
end;
// if CUSTOMER_TYPE = CUSTOMER_SHCD then
// begin
// // V3의 경우 2022년 부터 업데이트가 되지 않는다.
// // 확인해서 V3라면 업데이트 체크 주기를 조절해줌 23_0405 15:26:12 kku\
// if (dtLastAvCheck_ = 0) or (HoursBetween(dtLastAvCheck_, Now) > 4) then
// begin
// dtLastAvCheck_ := Now;
// var ini: TIniFile;
// Guard(ini, TiniFile.Create(CutFileExt(GetRunExePath) + '.ini'));
// ini.WriteDateTime('Customer', 'LastAvCheck', dtLastAvCheck_);
// end else exit;
// end;
if PrefModel_.VulAntiVirus then
begin
if (GetWscSecurityInfo(WSC_SECURITY_PROVIDER_ANTIVIRUS, PdList) > 0) and (HandleSecurity_ <> nil) then
HandleSecurity_.Update(PdList);
end;
// 사용하지 않아서 비활성 23_0406 09:41:13 kku
// if GetWscSecurityInfo(WSC_SECURITY_PROVIDER_ANTISPYWARE, PdList) > 0 then
// HandleSecurity_.Update(PdList);
end;
// 보안모드 종료 대기시간 체크 후 동작 추가 24_0820 14:05:21 kku - 음.... 보안모드 종료 동작 대기는 구현이 어려울거 같다 삭제 대기 24_0820 14:10:49 kku
// if PrefModel_.IsSecuEndActions and PrefModel_.IsUnsafeActions and (PrefModel_.UnsafeActionsMin > 0) and
// (VulService_ <> nil) and ( (GetTickCount - VulService_.UnsafeActionTick) <= (PrefModel_.UnsafeActionsMin * 1000) ) then
// begin
// VulService_.TryExitSafeMode(true);
// end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerCheckSecurity()');
end;
end;
procedure TManagerService.TimerCheckExpPo(aSender: TObject);
procedure InitExpPo;
begin
nExpPoMin_ := 0;
dtExpPoBegin_ := 0;
bIsExpPolicy_ := false;
llChkTimeSec_ := 0;
if PrefModel_.IsOldPolicy then
ExpPolicy.Clear
else if ((PrefExpPolicy_.InternalPoId = 'TEMP') or (PrefExpPolicy_.InternalPoId = 'false')) then
begin
PrefExpPolicy_.Clear;
PrefExpPolicy_.Save;
end;
end;
var
ullChk: ULONGLONG;
Label
LB_Detect;
begin
//exit;
try
if bIsExpPolicy_ then
begin
if (nExpPoMin_ = 9999) and not IsToday(dtExpPoBegin_) then // 하루, 24시간이 아니고 날짜가 바뀌면 끝
begin
InitExpPo;
exit;
end;
if MinutesBetween(Now, dtExpPoBegin_) >= nExpPoMin_ then
begin
InitExpPo;
exit;
end;
if CompareDateTime(Now, dtExpPoBegin_) = -1 then
begin
_Trace('Time change detected... 1');
InitExpPo;
exit;
end;
ullChk := SecondsBetween(Now, dtExpPoBegin_);
if ullChk < llChkTimeSec_ then
begin
_Trace('Time change detected... 2');
InitExpPo;
exit;
end;
llChkTimeSec_ := ullChk;
end else
ThdTaskTimer_.SetTask(TimerCheckExpPo, 1000, false);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerCheckExpPo()');
end;
end;
procedure UsbRestart;
var
szRestarProcessPath: string;
begin
szRestarProcessPath := GetRunExePathDir + 'usbrestart_x64.exe';
ExecutePath_hide(PChar(szRestarProcessPath), '');
end;
procedure TManagerService.TimerProcessDevTask(aSender: TObject);
var
PO: TPrefModel;
begin
//exit;
try
PO := GetModePolicy;
// USB 차단
// case PO.UsbBlockKind of
// ubkReadOnly :
// begin
// if ThdUsbMonRO_ = nil then
// begin
// ThdUsbMonRO_ := TThdUsbMon.Create(0, upkReadOnly);
// ThdUsbMonRO_.StartThread;
// _Trace('USB 읽기만 적용 - ON', 2);
// end;
// end;
// else
// begin
// if ThdUsbMonRO_ <> nil then
// begin
// FreeAndNil(ThdUsbMonRO_);
// _Trace('USB 읽기만 적용 - OFF', 2);
// end;
//_Trace('[MGKIM] TimerProcessDevTask .. UsbBlockKind(%d), IgrUsbSerialsKn(%s)',[DWORD(PO.UsbBlockKind), PO.IgrUsbSerialsKn]);
if PO.UsbBlockKind = ubkBlock then
begin
if bFltCtrlInit_ then
begin
if sExceptUsbDevKn_ <> PO.IgrUsbSerialsKn then
begin
sExceptUsbDevKn_ := PO.IgrUsbSerialsKn;
UpdateIgrUsbSerial4FltCtr(sExceptUsbDevKn_, DWORD(dsDisable));
end;
if not (FltCtrlPolicy_ = DWORD(dsDisable)) then
begin
_Trace('[MGKIM] Usb Disable!!!! .. (%s) <> (%s)',[sExceptUsbDevKn_, PO.IgrUsbSerialsKn]);
FltCtrl_.SetPolicy(DWORD(BDC_USB_DISK), DWORD(dsDisable), 1);
FltCtrl_.SetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsDisable), 1);
// FltCtrl_.SetPolicy(DWORD(BDC_USB), DWORD(dsDisable), DWORD(1));
//UsbRestart;
// DeviceGuard_.UsbReStart;
// DeviceGuard_.UsbPortApplyPolicy(dsDisable);
FltCtrlPolicy_ := DWORD(dsDisable);
end;
end;
end
else if PO.UsbBlockKind = ubkReadOnly then
begin
if bFltCtrlInit_ then
begin
_Trace('[MGKIM] Usb ReadOnly!!!! .. (%s) <> (%s)',[sExceptUsbDevKn_, PO.IgrUsbSerialsKn]);
if sExceptUsbDevKn_ <> PO.IgrUsbSerialsKn then
begin
sExceptUsbDevKn_ := PO.IgrUsbSerialsKn;
UpdateIgrUsbSerial4FltCtr(sExceptUsbDevKn_, DWORD(dsReadOnly));
end;
if not (FltCtrlPolicy_ = DWORD(dsReadOnly)) then
begin
FltCtrl_.SetPolicy(DWORD(BDC_USB_DISK), DWORD(dsReadOnly), 1);
FltCtrl_.SetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsReadOnly), 1);
FltCtrlPolicy_ := DWORD(dsReadOnly);
end;
end;
end
else begin
if not (FltCtrlPolicy_ = DWORD(dsEnable)) then
begin
sExceptUsbDevKn_ := '';
FltCtrl_.ClearUsbException;
FltCtrl_.SetPolicy(DWORD(BDC_USB_DISK), DWORD(dsEnable), 0);
FltCtrl_.SetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsEnable), 0);
// _Trace('Usb Enable!!!!');
// FltCtrl_.SetPolicy(DWORD(BDC_USB), DWORD(dsEnable), DWORD(1));
// DeviceGuard_.UsbPortApplyPolicy(dsEnable);
FltCtrlPolicy_ := DWORD(dsEnable);
end;
end;
DoEjectUsbDrives;
// end;
// end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerProcessDevTask()');
end;
end;
// BS1OutlookAddInClient.pas에서도 사용, 중요한 수정 시 함께 수정하도록.
procedure TManagerService.SetPatternList(sPatternOpt: String; var aList: TPatternEntList);
var
O: ISuperObject;
PtrnEnt, NewEnt: TPatternEnt;
StrList: TStringList;
i, nPos: Integer;
iter: TSuperObjectIter;
sName: String;
begin
try
aList.Clear;
if sPatternOpt = '' then
exit;
sPatternOpt := StringReplace(sPatternOpt, ';', '|', [rfReplaceAll]);
sPatternOpt := StringReplace(sPatternOpt, #13#10, '|', [rfReplaceAll]);
O := SO(sPatternOpt);
if O <> nil then
begin
if ObjectFindFirst(O, iter) then
begin
Repeat
if iter.key = 'scanoption' then
begin
Guard(StrList, TStringList.Create);
SplitString(O.S['scanoption'], '|', StrList);
for i := 0 to StrList.Count - 1 do
begin
PtrnEnt := MgPtn_.GetPatternEntByName(StrList[i]);
if PtrnEnt <> nil then
begin
NewEnt := TPatternEnt.Create(MgPtn_, nil);
NewEnt.AddName(MgPtn_.LangId, CttCodeToStr(StrList[i]));
NewEnt.PatternList.Add(PtrnEnt.GetSearchText);
aList.Add(NewEnt);
end;
end;
end else begin
sName := iter.key;
if sName.StartsWith('custom__') then
begin
Delete(sName, 1, 8);
// todo : 키워드, 패턴에 맞는 대응 필요?
nPos := Pos('__keyword', sName);
if nPos = 0 then
nPos := Pos('__pattern', sName);
if nPos > 0 then
begin
sName := Copy(sName, 1, nPos - 1);
PtrnEnt := aList.GetPtrnEntByName(sName);
if PtrnEnt = nil then
begin
PtrnEnt := TPatternEnt.Create(MgPtn_, nil);
PtrnEnt.AddName(MgPtn_.LangId, sName);
aList.Add(PtrnEnt);
end;
PtrnEnt.PatternList.Add(iter.val.AsString);
end;
end;
end;
Until not ObjectFindNext(iter);
ObjectFindClose(iter);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SetPatternList()');
end;
end;
procedure TManagerService.SetRuleToPtrnList(sRuleIds: String; var aList: TPatternEntList; bUseRName: Boolean = false);
var
sKwdPtrn: String;
i: Integer;
PtrnEnt: TPatternEnt;
begin
aList.Clear;
try
if sRuleIds = '' then
exit;
if bUseRName then
sKwdPtrn := MgRule_.GetRuleSearchStrFromIdsN(sRuleIds)
else
sKwdPtrn := MgRule_.GetRuleSearchStrFromIds(sRuleIds);
if sKwdPtrn <> '' then
begin
var CusList: TStringList;
Guard(CusList, TStringList.Create);
SplitString(sKwdPtrn, '**', CusList);
var InfoList: TStringList;
Guard(InfoList, TStringList.Create);
for i := 0 to CusList.Count - 1 do
begin
SplitString(CusList[i], '::', InfoList);
if InfoList.Count > 5 then
begin
PtrnEnt := TPatternEnt.Create(MgPtn_, nil, nil, StrToIntDef(InfoList[2], 1));
PtrnEnt.RType := ManagerPattern.TRuleType(StrToIntDef(InfoList[3], 0));
PtrnEnt.RSeverity := ManagerPattern.TRuleSeverity(StrToIntDef(InfoList[5], 0));
PtrnEnt.IsAnd := InfoList[4] = 'T';
PtrnEnt.AddName(MgPtn_.LangId, InfoList[0]);
PtrnEnt.PatternList.Add(InfoList[1]);
aList.Add(PtrnEnt);
end;
end;
// for i := 0 to CusList.Count - 1 do
// begin
// sPtrnEnt := CusList[i];
// nPos := Pos('::', sPtrnEnt);
// if nPos > 0 then
// begin
// sPtrnName := Copy(sPtrnEnt, 1, nPos - 1);
// Delete(sPtrnEnt, 1, nPos + 1);
// nPos := Pos('|*|', sPtrnEnt);
// if nPos > 0 then
// begin
// sPtrnVal := Copy(sPtrnEnt, 1, nPos - 1);
// Delete(sPtrnEnt, 1, nPos + 2);
// nCnt := StrToIntDef(sPtrnEnt, 1);
// end else begin
// sPtrnVal := sPtrnEnt;
// nCnt := 1;
// end;
//
// PtrnEnt := TPatternEnt.Create(MgPtn_, nil, nil, nCnt);
// PtrnEnt.AddName(MgPtn_.LangId, sPtrnName);
// PtrnEnt.PatternList.Add(sPtrnVal);
// aList.Add(PtrnEnt);
// end;
// end;
// var nPos: Integer := 0;
// var sPtrnName: String := '';
// var sPtrnEnt: String := '';
// for i := 0 to CusList.Count - 1 do
// begin
// sPtrnEnt := CusList[i];
// nPos := Pos('::', sPtrnEnt);
// if nPos > 0 then
// begin
// sPtrnName := Copy(sPtrnEnt, 1, nPos - 1);
// Delete(sPtrnEnt, 1, nPos + 1);
//
// PtrnEnt := TPatternEnt.Create(MgPtn_, nil);
// PtrnEnt.AddName(MgPtn_.LangId, sPtrnName);
// PtrnEnt.PatternList.Add(sPtrnEnt);
// aList.Add(PtrnEnt);
// end;
// end;
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. SetRuleToPtrnList()');
end;
end;
function TManagerService.GetModePolicy: TPrefModel;
var
PrevKind: TBS1ModeKind;
begin
Result := nil;
try
PrevKind := GetModeKind;
if bIsExpPolicy_ and PrefExpPolicy_.Loaded then
begin
// 오프라인 예외
Result := PrefExpPolicy_;
SetModeKind(hmkException);
SetModeName(RS_OfflineExpMode);
end else
if bIsOffline_ and PrefOffline_.Loaded then
begin
// 오프라인
Result := PrefOffline_;
SetModeKind(hmkOffline);
if IsCJ_Affiliates then
SetModeName(RS_UnverifiedMode)
else
SetModeName(RS_OfflineMode);
end else
if PrefVulModel_.Loaded and
(VulService_ <> nil) and
( VulService_.IsVpnOn and // 보안모드 이고
// bSchRstVul_ or // << 취약점 관리에서 처리함 22_1114 08:12:02 kku
( IsSafeExitImpossible and // VPN Client를 통한 보안모드가 아니고
not IsTemporaryConn and // 임시 접속 허용이 아니고
( not VulService_.IsSafeMode or // 취약 상태이고
not VulService_.IsWhiteApp or
( PrefModel.IsScanBlock and
not VulService_.IsSafePersonalInfo ) or // 개인정보 취약이고
( (PrefModel.PwChkTerm = pctBlock) and
not VulService_.IsPasswordSetTermOk ) or // 사용자 암호 변경 기간 만료
( (PrefModel.OsPatchCheck = opcCheck) and
// PrefModel.IsOsPatchCheck and // OS 패치 체크 상태에
// not PrefModel.IsOsPatchPopupOnly and // OS 패치 체크 시 팝업만 알림이 아니고
not VulService_.IsOsPatchUptoDate) )) // OS가 최신 상태가 아니면
) then
begin
Result := PrefVulModel_;
SetModeKind(hmkVulnerability);
SetModeName(RS_VulMode);
end else
// if { PrefIdlModel_.Loaded and } not VulService_.IsVpnOn then // 수면 모드는 정책 안불러와도 빈 정책을 줘야함 22_0729 07:46:15 kku
if not bIsServiceAvailable_ and not bIsManualSecurityMode_ then // VulService_.IsVpnOn 이걸로 체크 하면 모드별 팝업 옵션이 즉시 적용 되지 않아서 변경함 22_1222 17:08:48 kku
begin
Result := PrefIdlModel_;
SetModeKind(hmkSleep);
if IsHD then
SetModeName(RS_HEC_SleepMode)
else
SetModeName(RS_SleepMode);
end else begin
Result := PrefModel_;
SetModeKind(hmkSecurity);
if IsHD then
SetModeName(RS_HEC_SecuMode)
else
SetModeName(RS_SecuMode);
end;
// 모드가 변경 될때 처리할 사항 22_0812 07:36:22 kku
if PrevKind <> GetModeKind then
begin
// NicService_.WifiPopup := false;
dtChangeMode_ := Now;
if IsScreenLogo then
UpdateScreenLogo(true);
case GetModeKind of
hmkSleep :
begin
if Result.IsNotiSystem then
PopupMessage(TYPE_CHANGE_MODE, Format(RS_MsgChangeMode, [GetModeName]));
case PrevKind of
hmkSecurity :
begin
Randomize;
var n: Integer := Random(9);
if n = 3 then n := 9;
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\eCrmHomeEdition', 'caller', n, true);
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_SECURITY_END, 'Sleep mode');
_Trace('모드 변경 : 보안모드 > 수면모드', 1);
end;
hmkVulnerability :
begin
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_VULNER_END, 'Sleep mode');
_Trace('모드 변경 : 취약모드 > 수면모드', 1);
end;
hmkOffline :
begin
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_OFFLINE_END, 'Sleep mode');
_Trace('모드 변경 : 오프라인 > 수면모드', 1);
end;
hmkException :
begin
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_EXCEPTION_END, 'Sleep mode');
_Trace('모드 변경 : 예외모드 > 수면모드', 1);
end;
end;
end;
hmkSecurity :
begin
if Result.IsNotiSystem then
PopupMessage(TYPE_CHANGE_MODE, Format(RS_MsgChangeMode, [GetModeName]));
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\eCrmHomeEdition', 'caller', 3, true);
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_SECURITY_START, 'Security Mode');
case PrevKind of
hmkSleep : _Trace('모드 변경 : 수면모드 > 보안모드', 1);
hmkVulnerability : _Trace('모드 변경 : 취약모드 > 보안모드', 1);
hmkOffline : _Trace('모드 변경 : 오프라인 > 보안모드', 1);
hmkException : _Trace('모드 변경 : 예외모드 > 보안모드', 1);
end;
end;
hmkVulnerability :
begin
if Result.IsNotiSystem then
PopupMessage(TYPE_CHANGE_MODE, Format(RS_MsgChangeMode, [GetModeName]));
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_VULNER_START, 'Vulnerable mode');
case PrevKind of
hmkSleep : _Trace('모드 변경 : 수면모드 > 취약모드', 1);
hmkSecurity : _Trace('모드 변경 : 보안모드 > 취약모드', 1);
hmkOffline : _Trace('모드 변경 : 오프라인 > 취약모드', 1);
hmkException : _Trace('모드 변경 : 예외모드 > 취약모드', 1);
end;
end;
hmkOffline :
begin
if Result.IsNotiSystem then
begin
if IsCJ_Affiliates then
PopupMessage(TYPE_CHANGE_MODE, Format(RS_MsgChangeMode2, [GetModeName]))
else
PopupMessage(TYPE_CHANGE_MODE, Format(RS_MsgChangeMode2 + #13#10 + RS_WatchNetState, [GetModeName]));
end;
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_OFFLINE_START, 'Offline mode');
case PrevKind of
hmkSleep : _Trace('모드 변경 : 수면모드 > 오프라인', 1);
hmkSecurity : _Trace('모드 변경 : 취약모드 > 오프라인', 1);
hmkVulnerability : _Trace('모드 변경 : 오프라인 > 오프라인', 1);
hmkException : _Trace('모드 변경 : 예외모드 > 오프라인', 1);
end;
end;
hmkException :
begin
if Result.IsNotiSystem then
PopupMessage(TYPE_CHANGE_MODE, Format(RS_MsgChangeMode2, [GetModeName]));
gMgSvc.SendEventLog(URI_USER_ACTION, MODE_EXCEPTION_START, 'Exception mode');
case PrevKind of
hmkSleep : _Trace('모드 변경 : 수면모드 > 예외모드', 1);
hmkVulnerability : _Trace('모드 변경 : 취약모드 > 예외모드', 1);
hmkOffline : _Trace('모드 변경 : 오프라인 > 예외모드', 1);
hmkSecurity : _Trace('모드 변경 : 보안모드 > 예외모드', 1);
end;
end;
end;
end;
except
on E: Exception do
begin
ETgException.TraceException(Self, E, 'Fail .. GetModePolicy()');
if Result = nil then
Result := PrefModel_;
end;
end;
end;
procedure TManagerService.DeactivePolicyAll;
begin
if FileService_ <> nil then
FreeAndNil(FileService_);
if ThdWebUrl_ <> nil then
FreeAndNil(ThdWebUrl_);
if ThdInstMon_ <> nil then
FreeAndNil(ThdInstMon_);
if ThdBlueMon_ <> nil then
FreeAndNil(ThdBlueMon_);
if ThdMtpMon_ <> nil then
FreeAndNil(ThdMtpMon_);
if ThdPrintWork_ <> nil then
FreeAndNil(ThdPrintWork_);
if ThdPrinter_ <> nil then
FreeAndNil(ThdPrinter_);
FreeAndNil(EmDriveList_);
if ThdUsbMonRO_ <> nil then
FreeAndNil(ThdUsbMonRO_);
if ThdRouteMon_ <> nil then
FreeAndNil(ThdRouteMon_);
if ThdBlockAppMon_ <> nil then
FreeAndNil(ThdBlockAppMon_);
if ThdCltFld_ <> nil then
FreeAndNil(ThdCltFld_);
if ThdScreenRecord_ <> nil then
FreeAndNil(ThdScreenRecord_);
if ThdCapAppMon_ <> nil then
FreeAndNil(ThdCapAppMon_);
if MgHook_ <> nil then
FreeAndNil(MgHook_);
if ThdAppMon_ <> nil then
FreeAndNil(ThdAppMon_);
if ThdWndMon_ <> nil then
FreeAndNil(ThdWndMon_);
end;
function TManagerService.IsRunProcess(sChkProc: String; var sOldProc: String; OldProcList: TStringList; var bDetectProc: String): Boolean;
var
i: Integer;
ProcList: TStringList;
begin
Result := false;
try
bDetectProc := 'N/A';
if sChkProc = '' then
exit;
if sChkProc <> sOldProc then
begin
sOldProc := sChkProc;
SplitString(sOldProc, '|', OldProcList);
end;
Guard(ProcList, TStringList.Create);
ProcList.CaseSensitive := false;
if GetProcessNameToList(ProcList) > 0 then
begin
for i := 0 to OldProcList.Count - 1 do
if ProcList.IndexOf(OldProcList[i]) <> -1 then
begin
bDetectProc := OldProcList[i];
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsRunProcess()');
end;
end;
function TManagerService.IsUseProcess(sChkProc: String; var sOldProc: String; OldProcList: TStringList; var bDetectProc: String): Boolean;
var
h: HWND;
sCap, sPName: String;
llStyle: LONGLONG;
begin
Result := false;
try
bDetectProc := 'N/A';
if sChkProc = '' then
exit;
if sChkProc <> sOldProc then
begin
sOldProc := sChkProc;
SplitString(sOldProc, '|', OldProcList);
end;
h := FindWindow(nil, nil);
while h <> 0 do
begin
llStyle := GetWindowStyle(h);
if ((llStyle and WS_VISIBLE) <> 0) and
((llStyle and WS_MINIMIZE) = 0) then
begin
sCap := GetWindowCaption(h);
if sCap <> '' then
begin
sPName := GetProcessNameFromWndHandle(h);
if (sPName <> '') and (OldProcList.IndexOf(sPName) <> -1) then
begin
bDetectProc := sPName;
Result := true;
exit;
end;
end;
end;
h := GetWindow(h, GW_HWNDNEXT);
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsUseProcess()');
end;
end;
function TManagerService.IsUseUrl(sChkUrl: String; var sOldUrl: String; OldUrlList: TStringList; var bDetectUrl: String): Boolean;
var
i: Integer;
ProcList: TStringList;
sTgUrl: String;
hWB: HWND;
llStyle: LONGLONG;
begin
Result := false;
try
bDetectUrl := 'N/A';
if sChkUrl = '' then
exit;
if ThdWebUrl_ = nil then
exit;
sTgUrl := UpperCase(ThdWebUrl_.LastUrl);
if sTgUrl = '' then
exit;
hWB := ThdWebUrl_.LastHwnd;
if not IsWindow(hWB) then
exit;
llStyle := GetWindowStyle(hWB);
if ((llStyle and WS_VISIBLE) = 0) or
((llStyle and WS_MINIMIZE) <> 0) then exit;
if sChkUrl <> sOldUrl then
begin
sOldUrl := sChkUrl;
SplitString(sOldUrl, '|', OldUrlList);
end;
for i := 0 to OldUrlList.Count - 1 do
begin
if sTgUrl.Contains(UpperCase(OldUrlList[i])) then
begin
bDetectUrl := OldUrlList[i];
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsRunProcess()');
end;
end;
procedure TManagerService.OnWndNotify(aSender: TObject; hActiveWnd: HWND);
var
sPName: String;
begin
if bBlockOutlook_ then
begin
sPName := GetProcessNameFromWndHandle(hActiveWnd);
if CompareText(sPName, 'outlook.exe') = 0 then
begin
SendMessage(hActiveWnd, WM_CLOSE, 0, 0);
// TerminateProcessByPid(pEnt.dwPid);
if CUSTOMER_TYPE <> CUSTOMER_SKEC then
PopupMessage(TYPE_MSG_OUTLOOK_BLOCK, '');
end;
end;
end;
procedure TManagerService.OnAppNotify(aSender: TThdProcessWatch; pEnt: PPwEnt; aKind: TProcessWatchKind);
begin
try
case aKind of
pwkUnknown: ;
pwkInit,
pwkExecute:
begin
case CUSTOMER_TYPE of
CUSTOMER_DEV,
CUSTOMER_WELFNI,
CUSTOMER_WELFND :
begin
// 파수 복호화, 다운로더 실행 시 암호화 대응 기능 OFF 25_0112 14:25:16 kku
if SameText('FastDownloader.exe', pEnt.sPName) then
begin
if ThdReact_ <> nil then
begin
_Trace('FastDownloader.exe 실행됨. 암호화 대응 정지', 1);
ThdReact_.IgrEnt := true;
end;
end;
end;
end;
end;
pwkTerminated:
begin
case CUSTOMER_TYPE of
CUSTOMER_DEV,
CUSTOMER_WELFNI,
CUSTOMER_WELFND :
begin
if SameText('FastDownloader.exe', pEnt.sPName) then
begin
if ThdReact_ <> nil then
begin
_Trace('FastDownloader.exe 종료됨. 암호화 대응 재게', 1);
ThdReact_.IgrEnt := false;
end;
end;
end;
end;
DelOpenDocProc(pEnt.dwPid);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnAppNotify()');
end;
end;
procedure TManagerService.OnWaterEntNotify(Sender: TObject; const Item: PPrtWaterEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
begin
if FileExists(Item.sImgPath) then
DeleteDir(ExtractFilePath(Item.sImgPath));
Dispose(Item);
end;
end;
procedure TManagerService.OnFileExpNotify(Sender: TObject; const Item: PFileExpEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
procedure TManagerService.OnRecentFndNotify(Sender: TObject; const Item: PRecentFnd; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
procedure TManagerService.OnDpEntNotify(Sender: TObject; const Item: PDpEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
function TManagerService.GetAipUPN: String;
var
sTemp: String;
i: Integer;
begin
Result := '';
try
sTemp := GetProgramFilesDir + DIR_TG + INI_FORCEHE;
if FileExists(sTemp) then
begin
var ini: TIniFile;
Guard(ini, TIniFile.Create(sTemp));
sTemp := ini.ReadString('Force', 'AipId', '');
if sTemp <> '' then
begin
if CUSTOMER_TYPE = CUSTOMER_DEV then
begin
if StrToIntDef(sTemp, -100) = -100 then // 숫자로 안되어 있으면 적용, HEC 테스트를 편하게 하기 위함 24_0905 09:30:25 kku
Result := sTemp;
end else
Result := sTemp;
end;
end;
{$IFDEF DEBUG}
case CUSTOMER_TYPE of
CUSTOMER_UNITUS : Result := 'aiptest';
end;
{$ENDIF}
if Result = '' then
begin
case CUSTOMER_TYPE of
// CUSTOMER_HDENG : Result := sAccount_;
CUSTOMER_DEV,
CUSTOMER_UNITUS,
CUSTOMER_MOTRAS :
begin
var RkInfoList: TRkInfoList;
Guard(RkInfoList, TRkInfoList.Create);
if ExtrSubKeySortList(HKEY_USERS, RecentUserSid +
'\Software\Microsoft\Office\16.0\Common\LanguageResources\LocalCache\', RkInfoList) > 0 then
begin
Result := RkInfoList[0].sKName;
exit;
end;
var Reg: TRegistry;
Guard(Reg, TRegistry.Create);
sTemp := RecentUserSid + '\Software\Microsoft\Office\16.0\Common\DRM\UserSidEmailMapping';
if Reg.OpenKeyReadOnly(sTemp) then
begin
var DataList: TStringList;
Guard(DataList, TStringList.Create);
Reg.GetValueNames(DataList);
for i := 0 to DataList.Count - 1 do
begin
if DataList[i].ToUpper.EndsWith('_ADAL') then
begin
Result := Reg.ReadString(DataList[i]);
exit;
end;
end;
Reg.CloseKey;
end;
if Result = '' then
Result := GetRegValueAsString(HKEY_CLASSES_ROOT, 'Local Settings\Software\Microsoft\MSIPC\aip-addin', 'UPN');
end;
CUSTOMER_CJONS,
CUSTOMER_KDNVN :
begin
// Result := sEmail_;
// exit;
Result := 'BSOwner'; // BSOne AIP 모듈 권한으로 변경 24_1125 15:57:56 kku
end;
// CUSTOMER_JUVIS : Result := 'dkseo';
CUSTOMER_HCA : Result := 'test1';
CUSTOMER_SKEC : Result := 'BSOneAIP';
CUSTOMER_WHANIN : Result := 'injory';
end;
end;
if Result = '' then
begin
if CUSTOMER_TYPE = CUSTOMER_DEV then
Result := 'kjkim'
else
Result := sAccount_;
end;
case CUSTOMER_TYPE of
CUSTOMER_DEV : Result := Result + '@tocsgm365.onmicrosoft.com';
CUSTOMER_GEC,
CUSTOMER_HDENG : Result := Result + '@hec.co.kr';
// CUSTOMER_HAE : sAipDMail := sAipDMail + '@hyundai-autoever.com';
CUSTOMER_HCA : Result := Result + '@hkmc10.onmicrosoft.com'; // '@hmccloud10.onmicrosoft.com'; // PoC 24_0621 09:11:58 kku
// CUSTOMER_JUVIS : Result := Result + '@juvis.co.kr'; //'tocsg@juvis.co.kr'; // sAipDMail + '@juvis.co.kr';
CUSTOMER_KDNVN : Result := Result + '@kdiwin.com';
CUSTOMER_UNITUS : Result := Result + '@unitus.co.kr';
CUSTOMER_MOTRAS : Result := Result + '@motras.co.kr';
CUSTOMER_CJONS : Result := Result + '@cj.net';
CUSTOMER_SKEC : Result := Result + '@skec.com';
CUSTOMER_WHANIN : Result := Result + '@whanin.com';
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetAipUPN()');
end;
end;
function TManagerService.FindAipMdWnd(bForceUp: Boolean = false): HWND;
var
nTO: Integer;
sPath,
sFind, sFind2,
sPName, sAipDMail: String;
begin
Result := 0;
//{$IFDEF DEBUG}
// if CUSTOMER_TYPE <> CUSTOMER_DEV then
// exit;
//{$ENDIF}
if PrefModel_.AipOff then
exit;
if IsCJ_Affiliates and (sEmpNo_ = CJ_EMPTY_EMPNO) then
exit;
if AipFailCnt >= 10 then
begin
if (GetTickCount - dwAipExeTick_) >= 300000 {5분} then
begin
dwAipExeTick_ := 0;
AipFailCnt := 0;
end;
exit;
end;
if bWin7Ver_ then
exit;
sPath := GetAipPath;
// if (sPath = '') or not FileExists(sPath) then
if sPath = '' then
exit;
nTO := 0;
sFind2 := 'BSOne-AIP-T140713';
sFind := sFind2 + '-' + ExtractFileName(sPath);
if not bForceUp then
begin
Result := FindWindow(nil, PChar(sFind));
if Result = 0 then
Result := FindWindow(nil, PChar(sFind2)); // todo : 업데이트가 바로 안될경우를 대비해서 이전 식별자로 한번더 해준다.. 나중에 정리 필요
end;
if bForceUp or (Result = 0) then
begin
// 업데이트 확인
var sCurDir: String := GetRunExePathDir;
if FileExists(sCurDir + DIR_AIP17 + 'Microsoft.InformationProtection.dll') then
begin
if FileExists(sCurDir + DAT_AIPUP17) then
begin
if not FileExists(sCurDir + DIR_AIP17 + EXE_AIP) then
begin
DeleteFile(PChar(sCurDir + DAT_AIPUP17));
exit;
end;
end else begin
TerminateProcessByName(EXE_AIP);
// Sleep(1000);
if DeleteFile_wait(sCurDir + DIR_AIP17 + EXE_AIP) and
CopyFile(PChar(sCurDir + DIR_CONF + EXE_AIP17), PChar(sCurDir + DIR_AIP17 + EXE_AIP), false) and
FileExists(sCurDir + DIR_CONF + EXE_AIP17) then
begin
WriteLnFileEndUTF8(sCurDir + DAT_AIPUP17, DateTimeToStr(Now));
end;
// 이게 왜 사라지는지 모르겠지만... 보완 처리 23_1204 09:55:26 kku
if not FileExists(sCurDir + DIR_AIP17 + 'Newtonsoft.Json.dll') then
CopyFile(PChar(sCurDir + DIR_CONF + 'Newtonsoft.Json.dll'), PChar(sCurDir + DIR_AIP17 + 'Newtonsoft.Json.dll'), false);
end;
end else
if FileExists(sCurDir + DIR_AIP14 + 'Microsoft.InformationProtection.dll') then
begin
if FileExists(sCurDir + DAT_AIPUP) then
begin
if not FileExists(sCurDir + DIR_AIP14 + EXE_AIP) then
begin
DeleteFile(PChar(sCurDir + DAT_AIPUP));
exit;
end;
end else begin
TerminateProcessByName(EXE_AIP);
// Sleep(1000);
if DeleteFile_wait(sCurDir + DIR_AIP14 + EXE_AIP) and
CopyFile(PChar(sCurDir + DIR_CONF + EXE_AIP14), PChar(sCurDir + DIR_AIP14 + EXE_AIP), false) and
FileExists(sCurDir + DIR_CONF + EXE_AIP14) then
begin
WriteLnFileEndUTF8(sCurDir + DAT_AIPUP, DateTimeToStr(Now));
// DeleteFile(PChar(sCurDir + DIR_CONF + EXE_AIP14));
end;
// 이게 왜 사라지는지 모르겠지만... 보완 처리 23_1204 09:55:26 kku
if not FileExists(sCurDir + DIR_AIP14 + 'Newtonsoft.Json.dll') then
CopyFile(PChar(sCurDir + DIR_CONF + 'Newtonsoft.Json.dll'), PChar(sCurDir + DIR_AIP14 + 'Newtonsoft.Json.dll'), false);
end;
end;
// 모듈들 정상인지 크기로 확인 24_0221 15:12:34 kku
// CheckAip14Module() 보완 필요 25_0318 13:45:00 kku
// if FileExists(sCurDir + DIR_CONF + EXE_AIP14) and not CheckAip14Module then
// 백신등으로 파일 복사 시 간섭때문에 제대로 복사가 안되는 경우 크기가 0인 상태가 되는 경우가 있다 25_0806 08:59:46 kku
if GetFileSize_path(sPath) = 0 then
begin
DeleteFile(PChar(sCurDir + DAT_AIPUP17));
DeleteDir(sCurDir + DIR_AIP17);
DeleteFile(PChar(sCurDir + DAT_AIPUP));
DeleteDir(sCurDir + DIR_AIP14);
exit;
end;
sAipDMail := GetAipUPN;
if sAipDMail = '' then
exit;
_Trace('AIP 모듈 실행 .. %d', [AipFailCnt + 1], 1);
sPName := ExtractFileName(sPath);
while Result = 0 do
begin
if nTO > 10 then
break;
if GetProcessPidByName(sPName) = 0 then
begin
if not FileExists(sPath) then
break;
// {$IFDEF DEBUG}
// ExecuteApp(sPath, '-r', SW_HIDE);
// {$ELSE}
// ExecuteAppAsUser('explorer.exe', sPath, '-r', SW_HIDE);
// {$ENDIF}
// ExecutePath_hide(sPath, Format('-r %s', [sAipDMail])); // 차단으로 연결이 안되는 경우가 있다...
// ExecutePath(sPath, Format('-r %s', [sAipDMail])); // 차단으로 연결이 안되는 경우가 있다...
{$IFDEF DEBUG}
if ExecuteApp(sPath, Format('-r %s', [sAipDMail]), SW_SHOWNORMAL).hProcess <> 0 then
_Trace('AIP 모듈 실행 .. OK', [AipFailCnt + 1], 2);
{$ELSE}
if ExecuteApp(sPath, Format('-r %s', [sAipDMail]), SW_HIDE).hProcess <> 0 then
_Trace('AIP 모듈 실행 .. OK', [AipFailCnt + 1], 2);
{$ENDIF}
Sleep(1000);
end else
_Trace('AIP 모듈 실행 되어 있음', [AipFailCnt + 1], 3);
_Trace('AIP 모듈 핸들 검출중...', [AipFailCnt + 1], 3);
Result := FindWindow(nil, PChar(sFind));
if Result = 0 then
begin
Result := FindWindow(nil, PChar(sFind2)); // todo : 업데이트가 바로 안될경우를 대비해서 이전 식별자로 한번더 해준다.. 나중에 정리 필요
_Trace('AIP 모듈 핸들 검출 실패', [AipFailCnt + 1], 3);
end else
_Trace('AIP 모듈 핸들 검출 성공', [AipFailCnt + 1], 3);
Sleep(1000);
Inc(nTO);
end;
if Result = 0 then
begin
Inc(AipFailCnt);
dwAipExeTick_ := GetTickCount;
TerminateProcessByName(sPName);
_Trace('AIP 모듈 실행 .. 실패, DMail=%s, Path=%s', [sAipDMail, sPath], 1);
end else begin
AipFailCnt := 0;
dwAipExeTick_ := 0;
_Trace('AIP 모듈 실행 .. 성공', 1);
end;
end;
end;
// 음... 파일 변경 감시, 파일 생성 차단에서 "USB 연결 시에만" 옵션 사용 시
// 감시 기능 ON/OFF를 생각하고 만들었지만 이미 USB 파일만 수집, 처리되도록 만들어져서 그대로 진행함.
// 현재 아래 함수는 사용하지 않음 24_0213 14:27:47 kku
function TManagerService.IsUsbDrvConn: Boolean;
begin
Result := false;
try
if UsbConnList_ <> nil then
Result := UsbConnList_.Count > 0;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsUsbDrvConn()');
end;
end;
procedure TManagerService.UpdatePolicyActive(aPrefModel: TPrefModel);
var
i: Integer;
sTemp, sPath: String;
begin
try
if bDoCbUpdate_ then
begin
bDoCbUpdate_ := false;
if hRcvHwnd_ <> 0 then
PostMessage(hRcvHwnd_, WM_REFRESH_CLIPBOARDCHAIN, 0, 0);
end;
// OS 업데이트 패치 확인
if PrefModel_.OsPatchCheck <> opcNone then
begin
if ThdOsUpdateScan_ = nil then
begin
ThdOsUpdateScan_ := TThdWinUpdateScan.Create(hRcvHwnd_);
ThdOsUpdateScan_.StartThread;
_Trace('OS 업데이트 체크 - ON', 2);
end;
end else
if ThdOsUpdateScan_ <> nil then
begin
FreeAndNil(ThdOsUpdateScan_);
_Trace('OS 업데이트 체크 - OFF', 2);
end;
// 파일 태그 기능
if IsUsingFileTag then
begin
// if PrefModel_.UseFileTag then
// begin
// if (gClient = nil) {$IFNDEF DEBUG} and FileExists(GetRunExePathDir + EXE_SLCore) {$ENDIF} then
// begin
// SendMessage(hRcvHwnd_, WM_REQ_FILETAG_CONTROL, 1, 0);
// _Trace('파일 태그 - ON', 2);
// end;
// end else
// if gClient <> nil then
// begin
// SendMessage(hRcvHwnd_, WM_REQ_FILETAG_CONTROL, 0, 0);
// _Trace('파일 태그 - OFF', 2);
// end;
end;
if sTmpAcc_ <> WTS_GetActiveSessionUserName then
begin
// _Trace('활성 계정 변경 .. Old=%s, New=%s', [sTmpAcc_, WTS_GetActiveSessionUserName], 1);
_Trace('활성 계정 변경 .. %s', [WTS_GetActiveSessionUserName], 1);
if IsAccountEmpNo and (sTmpAcc_ <> '') then
begin
// 현재 세션의 explorer을 모두 종료
// todo : explorer 권한으로 실행 시 현재 세션 권한으로 실행하는 기능으로 보완 필요 25_1215 13:56:18 kku
TerminateProcessByName('explorer.exe');
Sleep(500);
ExecutePath_runAs('explorer.exe');
TerminateProcess(GetCurrentProcess, 10);
end else
_Trace('활성 계정 SID .. %s', [RecentUserSid], 1);
sTmpAcc_ := WTS_GetActiveSessionUserName;
end;
with aPrefModel do
begin
// 아웃룩 정책
if OutPo.bActive or (not IsOutlookABMonitorHook and (OutlookAB.Kind <> abkNone)) then
begin
if not ExistsKey(HKEY_CLASSES_ROOT, REG_BS1OutlookAddInKey) or
(not PrefModel_.NoOutlRcvr and not ExistsKey(HKEY_USERS, RecentUserSid + '\' + REG_OUTPLUG)) then
begin
if ExistsKey(HKEY_CLASSES_ROOT, REG_BS1OutlookAddInKey) then
begin
var sDir: String := GetRunExePathDir;
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sDir + DIR_CONF + DLL_ADDIN]));
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sDir + DIR_CONF + DLL_ADDIN64]));
end;
bBlockOutlook_ := true; // not bInitOutMail_;
end else begin
bBlockOutlook_ := false;
if gOutClient = nil then
begin
if hRcvHwnd_ <> 0 then
begin
SendMessage(hRcvHwnd_, WM_REQ_OUTLOOK_CONTROL, 1, 0);
_Trace('아웃룩 본문 탐지 - ON', 2);
end;
end else
if gOutClient.Connected then
begin
OutPo.bAttachLog := (not IsOutlookABMonitorHook and (OutlookAB.Kind = abkLog));
gOutClient.UpdateOutPo(aPrefModel);
end else
if not PrefModel_.NoOutlRcvr then
begin
i := GetRegValueAsInteger(HKEY_USERS, RecentUserSid + '\' + REG_OUTPLUG, 'LoadBehavior', -1);
if (i <> -1) and (i <> 3) then
begin
// 추가 기능에서 사용안함으로 변경 감지 25_1203 17:34:15 kku
SetRegValueInteger(HKEY_USERS, RecentUserSid + '\' + REG_OUTPLUG, 'LoadBehavior', 3);
TerminateProcessByName('outlook.exe');
_Trace('아웃룩 플러그인 사용안함 감지 ... 종료 처리', 2);
end;
end;
// if not gOutClient.Connected and (gOutClient.DeactiveW2W) then
// begin
// SendMessage(hRcvHwnd_, WM_REQ_OUTLOOK_CONTROL, 0, 0);
// _Trace('아웃룩 종료됨, 본문 탐지 - OFF', 2);
end;
end else
if gOutClient <> nil then
begin
bBlockOutlook_ := false;
if hRcvHwnd_ <> 0 then
begin
SendMessage(hRcvHwnd_, WM_REQ_OUTLOOK_CONTROL, 0, 0);
_Trace('아웃룩 본문 탐지 - OFF', 2);
end;
end else
if bBlockOutlook_ then
begin
bBlockOutlook_ := false;
end else
if CUSTOMER_TYPE = CUSTOMER_KIMCHANG then
begin
if ExistsKey(HKEY_CLASSES_ROOT, REG_BS1OutlookAddInKey)
and (GetProcessPidByName('outlook.exe') = 0) then
begin
_Trace('아웃룩 플러그인 감지, 제거 시도', 1);
var sDir: String := GetRunExePathDir;
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sDir + DIR_CONF + DLL_ADDIN]));
ExecutePath_hide('regsvr32.exe', Format('/u /s "%s"', [sDir + DIR_CONF + DLL_ADDIN64]));
end;
end;
// 기타 처리
if bBlockOutlook_ and not IsOutlookABMonitorHook then // 아웃룩 보안 플러그인 체크 추가 23_0504 12:53:49 kku
begin
if NotUseUAC then
begin
// 현대엔지니어링은 UAC 사용하지 않아서 일반 사용자 권한으로 설치 시도 25_1113 16:36:34 kku
if GetProcessPidByName('outlook.exe') = 0 then
InstallOutlookPlugIn_forHD(hRcvHwnd_);
end else
if ThdWndMon_ = nil then
begin
ThdWndMon_ := TThdActiveWndMon.Create;
ThdWndMon_.OnActiveWndNotify := OnWndNotify;
ThdWndMon_.StartThread;
_Trace('아웃룩 플러그인 미설치, 차단 활성 - ON', 2);
end;
end else
if ThdWndMon_ <> nil then
begin
FreeAndNil(ThdWndMon_);
_Trace('아웃룩 플러그인 미설치, 차단 활성 - OFF', 2);
end;
// if (FileMon.Kind <> fmkNone) and FileOpenMon then
// begin
// if RecentDocWatch_ = nil then
// begin
// RecentDocWatch_ := TRecentDocWatch.Create;
// RecentDocWatch_.StartService;
// _Trace('문서 열람, 감지 활성 - ON', 2);
// end;
// end else
// if RecentDocWatch_ <> nil then
// begin
// FreeAndNil(RecentDocWatch_);
// _Trace('문서 열람, 감지 활성 - OFF', 2);
// end;
// 상시로고 정책 (APP 조건)
if (ScreenLogo <> askNone) and (ScreenLogo <> askAlways) then
begin
var bOldVal := bForceScreenLogo_;
case ScreenLogo of
askNone : bForceScreenLogo_ := false;
askRunTargetOn :
begin
bForceScreenLogo_ := IsRunProcess(ScreenLogoApps, sScreenLogoChkApps_, ScreenLogoChkAppList, sTemp) or
(IsUrlCatchLogo and IsUseUrl(LogoUrlList, sScreenLogoChkUrls_, ScreenLogoChkUrlList, sTemp));
end;
askRunTargetOff :
begin
bForceScreenLogo_ := not IsRunProcess(ScreenLogoApps, sScreenLogoChkApps_, ScreenLogoChkAppList, sTemp) and
(IsUrlCatchLogo and not IsUseUrl(LogoUrlList, sScreenLogoChkUrls_, ScreenLogoChkUrlList, sTemp));
end;
askUseTargetOn :
begin
bForceScreenLogo_ := IsUseProcess(ScreenLogoApps, sScreenLogoChkApps_, ScreenLogoChkAppList, sTemp) or
(IsUrlCatchLogo and IsUseUrl(LogoUrlList, sScreenLogoChkUrls_, ScreenLogoChkUrlList, sTemp));
end;
askUseTargetOff :
begin
bForceScreenLogo_ := (not IsUseProcess(ScreenLogoApps, sScreenLogoChkApps_, ScreenLogoChkAppList, sTemp)) and
(IsUrlCatchLogo and not IsUseUrl(LogoUrlList, sScreenLogoChkUrls_, ScreenLogoChkUrlList, sTemp));
end;
end;
if (bOldVal <> bForceScreenLogo_) and (hRcvHwnd_ <> 0) then
begin
if bForceScreenLogo_ then
begin
SendEventLog(URI_USER_ACTION, PREVENT_SCREENLOGO_IF, 'Detected : ' + sTemp);
_Trace('상시 로고 (APP조건) - ON', 2);
end else begin
if sTemp = 'N/A' then
sTemp := 'ScreenLogo Clear';
SendEventLog(URI_USER_ACTION, RELEASE_SCREENLOGO_IF, sTemp);
_Trace('상시 로고 (APP조건) - OFF', 2);
end;
UpdateScreenLogo;
end;
end else
if (CUSTOMER_TYPE = CUSTOMER_DEMO) and (ScreenLogo = askAlways) then
begin
if ScreenLogoApps <> '' then
bIsAppUseScreenLogo_ := IsUseProcess(ScreenLogoApps, sScreenLogoChkApps_, ScreenLogoChkAppList, sTemp)
else if bIsAppUseScreenLogo_ then
bIsAppUseScreenLogo_ := false;
end else
if bForceScreenLogo_ then
begin
bForceScreenLogo_ := false;
UpdateScreenLogo;
end;
if IsScreenLogo then
begin
var bUpdate: Boolean := false;
// 모니터 연결/해제 감지 추가 23_1016 14:18:30 kku
if nMonitorCnt_ = 0 then
nMonitorCnt_ := GetSystemMetrics(SM_CMONITORS)
else
if nMonitorCnt_ <> GetSystemMetrics(SM_CMONITORS) then
begin
nMonitorCnt_ := 0;
bUpdate := true;
end;
if sScreenLogoData_ <> ScreenLogoData then
begin
sScreenLogoData_ := ScreenLogoData;
bUpdate := true;
end;
var wScreenVI: WORD := 0;
if ScreenLogoVisible then
wScreenVI := wScreenVI or 1;
if ScreenLogoInvisible then
wScreenVI := wScreenVI or (1 shl 1);
if wScreenVI_ = 0 then
wScreenVI_ := wScreenVI
else if wScreenVI_ <> wScreenVI then
begin
wScreenVI_ := wScreenVI;
bUpdate := true;
end;
if bUpdate then
UpdateScreenLogo(true);
end;
// 캡쳐 APP 차단 정책 (APP 조건)
if (ScreenBlockAppExp <> askNone) and (ScreenBlockAppExp <> askAlways) then
begin
var bOldVal := bForceScreenCapAppBlock_;
case ScreenBlockAppExp of
askRunTargetOn : bForceScreenCapAppBlock_ := IsRunProcess(ScreenBlockAppsExp, sScreenBlockChkApps_, ScreenBlockChkAppList, sTemp);
askRunTargetOff : bForceScreenCapAppBlock_ := not IsRunProcess(ScreenBlockAppsExp, sScreenBlockChkApps_, ScreenBlockChkAppList, sTemp);
askUseTargetOn : bForceScreenCapAppBlock_ := IsUseProcess(ScreenBlockAppsExp, sScreenBlockChkApps_, ScreenBlockChkAppList, sTemp);
askUseTargetOff : bForceScreenCapAppBlock_ := not IsUseProcess(ScreenBlockAppsExp, sScreenBlockChkApps_, ScreenBlockChkAppList, sTemp);
end;
if bForceScreenCapAppBlock_ and (bOldVal <> bForceScreenCapAppBlock_) then
begin
if bForceScreenLogo_ then
begin
SendEventLog(URI_USER_ACTION, PREVENT_CAPTUREAPP_IF, sTemp);
_Trace('캡쳐 APP 차단 (APP조건) - ON', 2);
end else begin
SendEventLog(URI_USER_ACTION, RELEASE_CAPTUREAPP_IF, sTemp);
_Trace('캡쳐 APP 차단 (APP조건) - OFF', 2);
end;
try
var ProcList: TStringList;
Guard(ProcList, TStringList.Create);
ProcList.CaseSensitive := false;
if GetProcessNameToList(ProcList) > 0 then
begin
for i := 0 to CapAppList_.Count - 1 do
begin
if ProcList.IndexOf(CapAppList_[i]) <> -1 then
begin
TerminateProcessByName(CapAppList_[i]);
if IsNotiBCA then
PopupMessage(TYPE_MSG_PREVENT_CAPAPP, CapAppList_[i] + '|PV');
SendEventLog(URI_USER_ACTION, PREVENT_CAPTURE_APP, 'Software Blocked : ' + CapAppList_[i]);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ForceScreenCapAppBlock');
end;
end;
end else
bForceScreenCapAppBlock_ := false;
// 컨텐츠 필터 기능 ON/OFF (파일 쓰기 감시, 파일 생성 차단, DRM)
if ((FileMon.Kind <> fmkNone) and FileMon.ContentFilter.bActive) or
((FileBlock.Kind <> fmkNone) and FileBlock.ContentFilter.bActive) or
DrmCF.bActive then
begin
if gKvKwdSch = nil then
SendMessage(hRcvHwnd_, WM_REQ_KWDSCH_CONTROL, 1, 0);
end else
if gKvKwdSch <> nil then
SendMessage(hRcvHwnd_, WM_REQ_KWDSCH_CONTROL, 0, 0);
// 파일 관련 정책
if (FileMon.Kind <> fmkNone) or
(FileBlock.Kind <> fmkNone) or
((GetModeKind = hmkSecurity) and PrefModel_.DrmCF.bActive) or
IsMasking or IsWaterMark or
((BlockFRename <> bfrFalse) and (BlockFRenames <> '')) or
((BlockFdRename <> bdrFalse) and (BlockDirFileRenames <> '')) or
IsPreventDownloads then
begin
if FileService_ = nil then
begin
FileService_ := TFileService.Create;
FileService_.StartService;
_Trace('파일 감시 활성화 (이름변경, 생성, 저장 감시등) - ON', 2);
end;
end else
if FileService_ <> nil then
begin
FreeAndNil(FileService_);
_Trace('파일 감시 활성화 (이름변경, 생성, 저장 감시등) - OFF', 2);
end;
// WIFI 무선네트워크 정보 확인을 위한 위치 서비스 강제 ON 25_0827 14:16:08 kku
if (WifiCtrlKind <> wckNone) and WifiGpsOn then
begin
i := 0;
if IsWifiPublicBlock then
i := 1
else
case WifiCtrlKind of
wckBlockName,
wckWhiteName: i := 1;
end;
if (i <> 0) then
begin
if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Windows\AppPrivacy', 'LetAppsAccessLocation') <> 1 then
begin
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Windows\AppPrivacy', 'LetAppsAccessLocation', 1, true);
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Windows\AppPrivacy', 'BsLaal', 1, true);
end;
end;
end else
if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Windows\AppPrivacy', 'BsLaal') = 1 then
begin
DelRegValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Windows\AppPrivacy', 'LetAppsAccessLocation');
DelRegValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Windows\AppPrivacy', 'BsLaal');
end;
// 반출 파일 목록 정리
if IsApproveSupport and ExFApproval then
OrganizeFileExpEnt;
// 설치 프로그램 감시
if AppInstKind <> aikNone then
begin
if ThdInstMon_ = nil then
begin
ThdInstMon_ := TThdInstMon.Create;
ThdInstMon_.StartService;
_Trace('소프트웨어 설치 감시 - ON', 2);
end;
end else
if ThdInstMon_ <> nil then
begin
FreeAndNil(ThdInstMon_);
_Trace('소프트웨어 설치 감시 - OFF', 2);
end;
// 도메인(URL) 수집
if (WebbMonKind <> wmkNone) or
( (Print.PrintKind <> pkNone) and
((Print.sPrintUrlExcepts <> '') or (PrtApvExpUrl <> '') or (PrtWtExpUrl <> '')) ) or
// ( ((WebbAB.Kind = abkUrlBlock) or (WebbAB.Kind = abkUrlAllow)) and
// (WebABUrlList <> '') ) or
(WebbAB.Kind <> abkNone) or // URL 수집을 위해 항상처리
IsUrlCatchLogo or // URL 조건 상시로고 추가 24_1218 10:50:38 kku
(CaptureBlockUrlKind <> bkNone) then
begin
if ThdWebUrl_ = nil then
begin
ThdWebUrl_ := TThdWebUrl.Create;
ThdWebUrl_.StartService;
_Trace('웹브라우저 감시 - ON', 2);
end;
end else
if ThdWebUrl_ <> nil then
begin
FreeAndNil(ThdWebUrl_);
_Trace('웹브라우저 감시 - OFF', 2);
end;
// 블루투스 감시, 차단
if BlueBlockKind <> dbkNone then
begin
if ThdBlueMon_ = nil then
begin
var bPvreventCurBT: Boolean := false;
var bExcept: Boolean;
var BTDevice: TBluetoothDevice;
Guard(BTDevice, TBluetoothDevice.Create);
BTDevice.RefreshBTDevice;
for i := 0 to BTDevice.Count - 1 do
bPvreventCurBT := bPvreventCurBT or ProcessPreventBT(BTDevice[i], bExcept);
ThdBlueMon_ := TThdBtDevNotify.Create;
ThdBlueMon_.PreventBtDevs := bPvreventCurBT;
ThdBlueMon_.OnChangeBTDevice := OnBtDevEntNotify;
ThdBlueMon_.StartThread;
_Trace('블루투스 감시 - ON', 2);
end;
end else
if ThdBlueMon_ <> nil then
begin
FreeAndNil(ThdBlueMon_);
_Trace('블루투스 감시 - OFF', 2);
end;
// MTP 감시, 차단
// todo : ThdMtpMon.pas에 정책 옵션 적용 필요
if MtpBlockKind <> ubkNone then
begin
if ThdMtpMon_ = nil then
begin
ThdMtpMon_ := TThdMtpMon.Create;
ThdMtpMon_.StartThread;
_Trace('MTP 감시 - ON', 2);
end;
end else
if ThdMtpMon_ <> nil then
begin
FreeAndNil(ThdMtpMon_);
_Trace('MTP 감시 - OFF', 2);
end;
// 프린트 워터마크 처리 추가 23_0627 15:22:59 kku
ProcessPrintWaterEnt;
// 프린터 감시, 차단
if (Print.PrintKind <> pkNone) or (Print.PrintWater <> pwNone) then // todo : 프린터 사용 감시 설정 확인
begin
if sPrintPatterns_ <> Print.ContentFilter.sPatterns then
sPrintPatterns_ := Print.ContentFilter.sPatterns;
if Print.PrintWater <> pwNone then
begin
if IsUsePrintWatermarkExpFile then
begin
if mtxPrtWater_ = nil then
mtxPrtWater_ := TTgMutex.Create(MUTEX_SHELL_EXPT_PRTWATER);
end;
end;
// if IsHD then
begin
// 최신 문서 확인 기능 ON
sTemp := RecentUserSid + '\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced';
if GetRegValueAsInteger(HKEY_USERS, sTemp, 'Start_TrackDocs', -99) <> 1 then
begin
if SetRegValueInteger(HKEY_USERS, sTemp, 'Start_TrackDocs', 1, true) then
_Trace('최신 문서 확인 ON 설정', 1)
else
_Trace('최신 문서 확인 ON 설정 실패..', 1);
end;
end;
if ThdPrinter_ = nil then
begin
// if IsHD then
// begin
// // 프린트 파일 경로를 잘 가져오기 위해 점프리스트 초기화 23_1220 08:42:30 kku
// ClearAutoJumpLists(GetUserNameFromReg);
// end;
ThdPrinter_ := TTgPrtSpoolWatch.Create(false);
ThdPrinter_.OnPrtNotificationEvent := OnPtrJobNotify;
ThdPrinter_.StartThread;
ThdPrintWork_ := TThdPrintWork.Crate;
ThdPrintWork_.StartThread;
_Trace('프린터 감시 - ON', 2);
end;
end else
if ThdPrinter_ <> nil then
begin
if ThdPrintWork_ <> nil then
FreeAndNil(ThdPrintWork_);
FreeAndNil(ThdPrinter_);
if mtxPrtWater_ <> nil then
FreeAndNil(mtxPrtWater_);
_Trace('프린터 감시 - OFF', 2);
end;
// 클립보드 컨텐츠 필터 업데이트
if (ClipBlockKind <> cbkNone) and CbCF.bActive then
begin
// DoClipboardUpdate;
if CbCF.bActive then
begin
if sCbPatterns_ <> CbCF.sPatterns then
begin
sCbPatterns_ := CbCF.sPatterns;
SetRuleToPtrnList(sCbPatterns_, CbPatternEnts_)
end;
end;
end;
// DRM 열람 권한
// if (GetModeKind = hmkSecurity) and (DrmAccessKind <> dakNone) then
// begin
// if mtxDrmOpen_ = nil then
// mtxDrmOpen_ := TTgMutex.Create(MUTEX_SHELL_DRMOPEN);
// end else
// if mtxDrmOpen_ <> nil then
// FreeAndNil(mtxDrmOpen_);
// API 훅 관련 정책 체크
// DRM, 프린트 워터마크, 파일 첨부/사용 차단
// if IsNeedHook or
// MutexExists(MUTEX_SHELL_DRMOPEN) then // 서버 정책에 DRM 정책이 들어간다면 IsNeedHook에 포함 시켜야 함
// 경동 나비엔은 훅 기능 없어도 항상 실행 체크 24_1126 14:22:50 kku
// if CUSTOMER_TYPE = CUSTOMER_KDNVN then
if CUSTOMER_TYPE = CUSTOMER_DEV then
begin
if bFirstAip_ then
FindAipMdWnd;
end else
if IsSupportAIP or IsUseEncOnlyAIP then
FindAipMdWnd;
{$IFNDEF DEBUG1}
if IsNeedHook then
begin
// if IsSupportAIP and (CUSTOMER_TYPE <> CUSTOMER_KDNVN) then
// FindAipMdWnd;
if sWebABPatterns_ <> WebbAB.ContentFilter.sPatterns then
sWebABPatterns_ := WebbAB.ContentFilter.sPatterns;
if sEtcABPatterns_ <> EtcAB.ContentFilter.sPatterns then
sEtcABPatterns_ := EtcAB.ContentFilter.sPatterns;
if sOutABPatterns_ <> OutlookAB.ContentFilter.sPatterns then
sOutABPatterns_ := OutlookAB.ContentFilter.sPatterns;
if IntBtBlockNewFile.contentsFilter_use then
begin
if BtcontentsFilter_list_ <> IntBtBlockNewFile.contentsFilter_list then
BtcontentsFilter_list_ := IntBtBlockNewFile.contentsFilter_list
end else
BtcontentsFilter_list_ := '';
if IntUsbBlockNewFile.contentsFilter_use then
begin
if UsbcontentsFilter_list_ <> IntUsbBlockNewFile.contentsFilter_list then
UsbcontentsFilter_list_ := IntUsbBlockNewFile.contentsFilter_list
end else
UsbcontentsFilter_list_ := '';
if IntUsbToUsbBlockNewFile.contentsFilter_use then
begin
if UsbToUsbcontentsFilter_list_ <> IntUsbToUsbBlockNewFile.contentsFilter_list then
UsbToUsbcontentsFilter_list_ := IntUsbToUsbBlockNewFile.contentsFilter_list
end else
UsbToUsbcontentsFilter_list_ := '';
if IntCdromBlockNewFile.contentsFilter_use then
begin
if CdromcontentsFilter_list_ <> IntCdromBlockNewFile.contentsFilter_list then
CdromcontentsFilter_list_ := IntCdromBlockNewFile.contentsFilter_list
end else
CdromcontentsFilter_list_ := '';
if IntMtpBlockNewFile.contentsFilter_use then
begin
if MtpcontentsFilter_list_ <> IntMtpBlockNewFile.contentsFilter_list then
MtpcontentsFilter_list_ := IntMtpBlockNewFile.contentsFilter_list
end else
MtpcontentsFilter_list_ := '';
if MgHook_ = nil then
begin
if DrmAccessKind <> dakNone then
begin
// Acrobat DLL후킹 보안 해제 24_0130 10:41:29 kku
var sRegPath: String := RecentUserSid + '\Software\Adobe\Adobe Acrobat\DC\';
// var ini: TIniFile;
// Guard(ini, TiniFile.Create(CutFileExt(GetRunExePath) + '.ini'));
if ExistsKey(HKEY_USERS, sRegPath) then
begin
SetRegValueInteger(HKEY_USERS, sRegPath + 'TrustManager', 'bEnhancedSecurityInBrowser', 0, true);
SetRegValueInteger(HKEY_USERS, sRegPath + 'TrustManager', 'bEnhancedSecurityStandalone', 0, true);
SetRegValueInteger(HKEY_USERS, sRegPath + 'Privileged', 'bProtectedMode', 0, true);
end;
end;
MgHook_ := TManagerHook.Create;
MgHook_.StartHookWatch;
_Trace('APP 제어 (Hook) - ON', 2);
// var NpClient: TTgNpClient;
// Guard(NpClient, TTgNpClient.Create(PIPE_NAME));
// if NpClient.Connect then
// begin
// // NpClient.Disconnect;
// end;
end else begin
if MgHook_.IsChangeHookPolicy(aPrefModel) then
MgHook_.UpdateHookTarget;
end;
end else
if (MgHook_ <> nil) then
begin
FreeAndNil(MgHook_);
sWebABPatterns_ := '';
sEtcABPatterns_ := '';
sOutABPatterns_ := '';
_Trace('APP 제어 (Hook) - OFF', 2);
end;
{$ENDIF}
// USB 차단 // TimerProcessDevTask() 여기서 처리하도록 변경 25_1113 11:11:24 kku
// case UsbBlockKind of
// ubkReadOnly :
// begin
// if ThdUsbMonRO_ = nil then
// begin
// ThdUsbMonRO_ := TThdUsbMon.Create(0, upkReadOnly);
// ThdUsbMonRO_.StartThread;
// _Trace('USB 읽기만 적용 - ON', 2);
// end;
// end;
// else
// begin
// if ThdUsbMonRO_ <> nil then
// begin
// FreeAndNil(ThdUsbMonRO_);
// _Trace('USB 읽기만 적용 - OFF', 2);
// end;
//
// if UsbBlockKind = ubkBlock then
// DoEjectUsbDrives;
// end;
// end;
// if sEjectWbDrive_ <> '' then
// begin
// if hEjectWbDrive_ <> 0 then
// begin
// CloseHandle(hEjectWbDrive_);
// hEjectWbDrive_ := 0;
// end;
//
// if IsReadOnlyByWriteProbe(sEjectWbDrive_) = 1 then
// begin
// if ThdUsbMonRO_ <> nil then
// ThdUsbMonRO_.SetRecoverWB(false);
// try
// var DriveInfo: TDriveInfo;
// GetDriveDetail(sEjectWbDrive_, @DriveInfo);
// SetReadOnly(sEjectWbDrive_, DriveInfo.nDiskNum, false);
// Sleep(500);
// if IsReadOnlyByWriteProbe(sEjectWbDrive_) <> 1 then
// EjectDrive(sEjectWbDrive_, nil, false, true);
// finally
// if ThdUsbMonRO_ <> nil then
// ThdUsbMonRO_.SetRecoverWB(true);
// end;
// end;
// sEjectWbDrive_ := '';
// end;
// CD/DVD 차단
// _Trace('[MGKIM] CdromBlockKind : %d', [DWORD(CdromBlockKind)]);
if CdromBlockKind = ubkBlock then
begin
DoEjectCDROM;
FltCtrl_.SetPolicy(DWORD(BDC_CDROM), DWORD(dsDisable), 0);
end
else if (CdromBlockKind = ubkReadOnly) and (backupCdromBlockKind <> ubkReadOnly) then
begin
FltCtrl_.SetPolicy(DWORD(BDC_CDROM), DWORD(dsReadOnly), 0);
if GetModePolicy.CDPopup then
PopupMessage(TYPE_MSG_PREVENT_CDROM, 'ReadOnly');
backupCdromBlockKind := CdromBlockKind;
end
else
FltCtrl_.SetPolicy(DWORD(BDC_CDROM), DWORD(dsEnable), 0);
// 라우팅테이블 변경 차단
if RouteEnable then
begin
if ThdRouteMon_ = nil then
begin
ThdRouteMon_ := TThdRouteMon.Create;
ThdRouteMon_.StartThread;
_Trace('라우팅 테이블 감시 - ON', 2);
end;
end else
if ThdRouteMon_ <> nil then
begin
FreeAndNil(ThdRouteMon_);
_Trace('라우팅 테이블 감시 - OFF', 2);
end;
// 캡쳐 앱 차단 >> 순서 중요 : 캡쳐 APP 차단 정책 (APP 조건) 보다 아래여야 함
if bForceScreenCapAppBlock_ or (CapAppMonKind <> camNone) then
begin
if ThdCapAppMon_ = nil then
begin
ThdCapAppMon_ := TThdProcessWatch.Create(false);
ThdCapAppMon_.OnProcessWatchNotify := OnCapAppNotify;
ThdCapAppMon_.StartThread;
_Trace('캡쳐 APP 차단 - ON', 2);
end;
end else
if ThdCapAppMon_ <> nil then
begin
FreeAndNil(ThdCapAppMon_);
_Trace('캡쳐 APP 차단 - OFF', 2);
end;
// 소프트웨어 실행 차단
if IsBlockApp or IsMonApp then
begin
bIsMonApp_ := IsMonApp;
bIsBlockApp_ := IsBlockApp;
if bIsMonApp_ and (sMonApps_ <> MonAppList) then
begin
sMonApps_ := MonAppList;
SplitString(sMonApps_, '|', MonAppList_);
end;
if bIsBlockApp_ and (sBlockApps_ <> SoftwareListB) then
begin
sBlockApps_ := SoftwareListB;
if Pos(';', sBlockApps_) > 0 then
SplitString(sBlockApps_, '|', BlockAppList_) // |로 바꿨는데 이전 버전에서 저장된 정책 호환을 위해 잠시만 이렇게 처리하는거 추가, todo : 나중에 삭제 필요 25_0121 15:46:20 kku
else
SplitString(sBlockApps_, '|', BlockAppList_);
BlockAppWList_.Clear;
for i := BlockAppList_.Count - 1 downto 0 do
begin
if BlockAppList_[i].Contains('*') then
begin
BlockAppWList_.Add(BlockAppList_[i]);
BlockAppList_.Delete(i);
end;
end;
end;
if ThdBlockAppMon_ = nil then
begin
ThdBlockAppMon_ := TThdProcessWatch.Create(false, true);
ThdBlockAppMon_.OnProcessWatchNotify := OnBlockAppNotify;
ThdBlockAppMon_.StartThread;
_Trace('APP 실행 차단, 사용 감시 - ON', 2);
end;
end else
if ThdBlockAppMon_ <> nil then
begin
bIsMonApp_ := false;
bIsBlockApp_ := false;
FreeAndNil(ThdBlockAppMon_);
_Trace('APP 실행 차단, 사용 감시 - OFF', 2);
end;
// APP 동영상 녹화
if (ShowTestFun or (CUSTOMER_TYPE = CUSTOMER_LGD)) and
AppRcdActive and DirectoryExists(GetRunExePathDir + DIR_CONF + 'avlib\') then
begin
if ThdScreenRecord_ = nil then
begin
ThdScreenRecord_ := TThdScreenRecord.Create(hRcvHwnd_);
ThdScreenRecord_.StartThread;
_Trace('APP 동영상 녹화 - ON', 2);
end;
end else
if ThdScreenRecord_ <> nil then
begin
FreeAndNil(ThdScreenRecord_);
_Trace('APP 동영상 녹화 - OFF', 2);
end;
// 복호화 가능 여부
if IsExplorerDrmMenu and IsDrmDecrypt then
begin
if mtxDrmDec_ = nil then
mtxDrmDec_ := TTgMutex.Create(MUTEX_SHELL_DRMDEC);
end else
if mtxDrmDec_ <> nil then
FreeAndNil(mtxDrmDec_);
// AutoRun 방지
if AutoRunBlock then
begin
if sAutoRunBlockKey_ = '' then
begin
var sSid: String := RecentUserSid;
if sSid <> '' then
sAutoRunBlockKey_ := sSid + '\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer';
end;
if sAutoRunBlockKey_ <> '' then
begin
if GetRegValueAsInteger(HKEY_USERS, sAutoRunBlockKey_, 'NoDriveTypeAutoRun') <> $FF then
begin
SetRegValueInteger(HKEY_USERS, sAutoRunBlockKey_, 'NoDriveTypeAutoRun', $FF, true);
_Trace('USB AutoRun 방지 - ON', 2);
end;
end;
end else
if sAutoRunBlockKey_ <> '' then
begin
DelRegValue(HKEY_USERS, sAutoRunBlockKey_, 'NoDriveTypeAutoRun');
sAutoRunBlockKey_ := '';
_Trace('USB AutoRun 방지 - OFF', 2);
end;
if bIsScreenLogoBold_ <> (bIsIdleScreenLogo_ or bIsIpMatchScreenLogo_ or bIsRdpLogonScreenLogo_ or bIsAppUseScreenLogo_) then
begin
if bIsScreenLogoBold_ then
SendEventLog(URI_USER_ACTION, PREVENT_SCREENLOGO_BOLD, 'Screen Logo : Normal')
else
SendEventLog(URI_USER_ACTION, PREVENT_SCREENLOGO_THIN, 'Screen Logo : Bold');
bIsScreenLogoBold_ := bIsIdleScreenLogo_ or bIsIpMatchScreenLogo_ or bIsRdpLogonScreenLogo_ or bIsAppUseScreenLogo_;
UpdateScreenLogo(true);
end;
// 시간 변경 체크
if dtLastChk_ <> 0 then
begin
var dtNow: TDateTime := Now;
var bChangeDT: Boolean := CompareDateTime(Now, dtLastChk_) = -1;
if bChangeDT or (SecondsBetween(dtNow, dtLastChk_) > 120) then
begin
_Trace('시간 변경 감지됨. OldDT=%s, NewDT=%s', [DateTimeToStr(dtLastChk_), DateTimeToStr(dtNow)]);
if PrefModel_.BlockChangeTime then
begin
if SetLocalTime(ConvDateTimeToSystemTime_Local(IncSecond(dtLastChk_))) then // todo : 개선필요...
begin
_Trace('시간 변경 차단 성공 .. %s', [DateTimeToStr(Now)]);
SendEventLog(URI_USER_ACTION, SYSEVT_PROTECT_PCTIME,
Format('OldDT=%s, NewDT=%s', [DateTimeToStr(dtLastChk_), DateTimeToStr(dtNow)]))
end else
_Trace('시간 변경 차단 실패 .. Error=%d', [GetLastError]);
end;
end;
end;
dtLastChk_ := Now;
{$IFNDEF DEBUG}
// 크롬, 엣지 시작페이지 변경 for 알라딘
if CUSTOMER_TYPE = CUSTOMER_ALADIN then
begin
if PrefModel_.IsShowAInfo then
begin
var bMakeRKey: Boolean;
bMakeRKey := ExistsKey(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge');
if not bMakeRKey then
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge', 'BS1', 9, true);
if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge', 'RestoreOnStartup') <> 5 then
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge', 'RestoreOnStartup', 5, true);
if GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge', 'NewTabPageLocation') <> 'about:blank' then
SetRegValueString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge', 'NewTabPageLocation', 'about:blank', true);
bMakeRKey := ExistsKey(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome');
if not bMakeRKey then
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome', 'BS1', 9, true);
if GetRegValueAsInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome', 'RestoreOnStartup') <> 5 then
SetRegValueInteger(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome', 'RestoreOnStartup', 5, true);
if GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome', 'NewTabPageLocation') <> 'about:blank' then
SetRegValueString(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome', 'NewTabPageLocation', 'about:blank', true);
end else begin
if GetRegValueAsInteger(HKEY_LOCAL_MACHINE,
'SOFTWARE\Policies\Microsoft\Edge', 'BS1') = 9 then
DelRegKey(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Microsoft\Edge');
if GetRegValueAsInteger(HKEY_LOCAL_MACHINE,
'SOFTWARE\Policies\Google\Chrome', 'BS1') = 9 then
DelRegKey(HKEY_LOCAL_MACHINE, 'SOFTWARE\Policies\Google\Chrome');
end;
end;
{$ENDIF}
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdatePolicyActive()');
end;
end;
procedure TManagerService.SetSchRstVul(bVal: Boolean);
begin
if bSchRstVul_ <> bVal then
begin
bSchRstVul_ := bVal;
AgentModel_.ForceVulMode := bSchRstVul_;
AgentModel_.Save;
// if bSchRstVul_ then
// SetRegValueInteger(HKEY_LOCAL_MACHINE, REG_HE, 'SchRstVul', 1, true)
// else
// DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'SchRstVul');
RefreshView;
end;
end;
procedure TManagerService.LoadSchRstVul;
begin
SetSchRstVul(AgentModel_.ForceVulMode and (PrefModel_.PersonalInfoFileMax > 0)); // or
// (GetRegValueAsInteger(HKEY_LOCAL_MACHINE, REG_HE, 'SchRstVul') = 1));
end;
function TManagerService.GetIsRestricDate: Boolean;
begin
// 접속 승인과 만료일이 AND에서 OR로 바껴서
// 만료일 표시가 의미 없어졌다.
// 접속 승인 OFF 했는데 만료일도 끝났다면 무조건 만료일 문제로 뜨기 때문에
// 사용하지 않는걸로 보완 22_1111 09:05:03 kku
Result := false; // PrefModel_.IsRestricDate;
end;
procedure TManagerService.ProcessReleaseQuarantineFiles;
var
sInfo, sPath, sDestUrl: String;
O: ISuperObject;
i: Integer;
ms: TMemoryStream;
begin
try
sInfo := GetQuarantineInfo(DestServerUrl, HTTP_, sUserName_);
if sInfo = '' then
exit;
O := SO(sInfo);
if O.S['result'] <> 'true' then
begin
_Trace('Fail .. ReleaseQuarantineFiles() .. result = false', 2);
exit;
end;
if O.O['rtnMap'] = nil then
begin
_Trace('Fail .. ReleaseQuarantineFiles() .. List Empty', 2);
exit;
end;
if O.O['rtnMap'].DataType <> stArray then
begin
_Trace('Fail .. ReleaseQuarantineFiles() .. Invalid List', 2);
exit;
end;
sDestUrl := StringReplace(DestServerUrl, 'agentLogRequest.do', 'quarantineFileDownload/', [rfReplaceAll]);
sDestUrl := StringReplace(sDestUrl, 'agentLogRequests.do', 'quarantineFileDownload/', [rfReplaceAll]);
Guard(ms, TMemoryStream.Create);
for i := 0 to O.A['rtnMap'].Length - 1 do
begin
if O.A['rtnMap'].O[i].S['offYn'] = 'T' then
begin
sPath := O.A['rtnMap'].O[i].S['filepath'];
// if FileExists(sPath) then
// DeleteFileForce(sPath);
ms.Clear;
try
HTTP_.Get(sDestUrl + IntToStr(O.A['rtnMap'].O[i].I['idx']), ms);
// if not FileExists(sPath) and (ms.Size > 0) then
// ms.SaveToFile(sPath);
if FileExists(sPath) then
DeleteFileForce(sPath);
ms.SaveToFile(sPath);
gMgSvc.PopupMessage(TYPE_MSG_RELEASE_QUARANTINE_FILE, sPath);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. QuarantineFile Download .. FName=%s', [ExtractFileName(sPath)])
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessReleaseQuarantineFiles()');
end;
end;
function TManagerService.GetLastPolicy: String;
begin
if sLastPolicy_ = '' then
begin
var dt: TDateTime := JavaToDelphiDateTime(StrToInt64Def(GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'LP'), 0));
if PrefModel_.Loaded and (dt <> 0) then
sLastPolicy_ := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt)
else
sLastPolicy_ := '1999-01-01 01:01:01';
end;
Result := sLastPolicy_;
end;
procedure TManagerService.SetLastPolicy(sLP: String);
begin
if sLastPolicy_ <> sLP then
begin
sLastPolicy_ := sLP;
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'LP',
IntToStr(DelphiToJavaDateTime(StrToDateTime(sLastPolicy_))), true);
end;
end;
procedure TManagerService.UpdateIgrUsbSerial4FltCtr(sData: String ; FltCtrlPolicy : DWORD);
var
ExpList, InfoList: TStringList;
i: Integer;
DevInfo: TDevInfo;
begin
// _Trace('[MGKIM] UpdateIgrUsbSerial4FltCtr .. begin bFltCtrlInit(%d)(%d)',[DWORD(bFltCtrlInit_), FltCtrlPolicy]);
if not bFltCtrlInit_ or (FltCtrlPolicy = 0) then
exit;
try
FltCtrl_.ClearUsbException;
Guard(ExpList, TStringList.Create);
SplitString(sData, '|', ExpList, false, true);
Guard(InfoList, TStringList.Create);
// _Trace('[MGKIM] UpdateIgrUsbSerial4FltCtr .. (%s), ExpList.Count(%d)',[sData, ExpList.Count]);
for i := 0 to ExpList.Count - 1 do
begin
SplitString(ExpList[i], '&', InfoList);
// _Trace('[MGKIM] UpdateIgrUsbSerial4FltCtr .. InfoList.Count(%d)',[InfoList.Count]);
if InfoList.Count = 3 then
begin
var vid: DWORD;
var pid: DWORD;
// _Trace('[MGKIM] UpdateIgrUsbSerial4FltCtr.. PID: %s, VID: %s, Serial: %s',[InfoList[0], InfoList[1],InfoList[2]]);
vid:= StrToIntDef('$' + InfoList[0], 0);
pid:= StrToIntDef('$' + InfoList[1], 0);
DeviceGuard_.AddUsbPortExcept(InfoList[0], InfoList[1],InfoList[2]);
if (vid <> 0) and (pid <> 0) then
begin
// _Trace('[MGKIM] UpdateIgrUsbSerial4FltCtr.. Port PID: %x, VID: %x, Serial: %s',[vid, pid,InfoList[2]]);
FltCtrl_.SetUsbPortException(vid, pid, 0, PChar(InfoList[2]));
end;
FltCtrl_.SetUsbException(PChar(InfoList[0]), PChar(InfoList[1]), 0, PChar(InfoList[2]));
// _Trace('[MGKIM] UpdateIgrUsbSerial4FltCtr.. end');
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateIgrUsbSerial4FltCtr()');
end;
end;
procedure TManagerService.UpdateFltCtrlEnts(sDrive, sDevInfo: String);
begin
Lock;
try
sDrive := sDrive.ToUpper;
if DcFltCtrlEnt_.ContainsKey(sDrive) then
DcFltCtrlEnt_[sDrive] := sDevInfo
else
DcFltCtrlEnt_.Add(sDrive, sDevInfo);
finally
Unlock;
end;
end;
function TManagerService.GetFltCrltEntInfo(sDrive: String): String;
function GetSameSerialDevs(sSerial: String; var nSameCnt: Integer): String;
var
enum: TEnumerator<String>;
begin
Result := '';
Lock;
try
Guard(enum, DcFltCtrlEnt_.Values.GetEnumerator);
while enum.MoveNext do
begin
if enum.Current.EndsWith(sSerial) then
begin
SumString(Result, enum.Current, '<!>');
Inc(nSameCnt);
end;
end;
finally
Unlock;
end;
end;
begin
Result := '';
Lock;
try
sDrive := sDrive.ToUpper;
if DcFltCtrlEnt_.ContainsKey(sDrive) then
Result := DcFltCtrlEnt_[sDrive];
finally
Unlock;
end;
if Result <> '' then
begin
var nSameCnt: Integer := 0;
var sSerial: String := ExtrLastDelimiterStr(Result, '§');
var sSame: String;
// 오래된 SD 멀티 허브의 경우 빈드라이브가 여러개 생성되는데
// 이거 모두 동일한 시리얼로 인식될 경우 정보 모두 처리하도록 보완 25_0202 14:43:43 kku
sSame := GetSameSerialDevs(sSerial, nSameCnt);
if nSameCnt > 1 then
Result := sSame;
end;
end;
procedure TManagerService.ProcessUSBArrival(sDrive: String);
var
nType: Integer;
sMsg: String;
llSize: LONGLONG;
UsbBlockKind: TUsbBlockKind;
DevBlockKind: TUsbBlockKind;
bCdrom: Boolean;
DriveInfo: TDriveInfo;
Label
LB_ProcCDROM;
begin
// _Trace('ProcessUSBArrival() .. 1');
try
try
// 보안, 가상 드라이브의 경우 연결 이벤트가 여러번 발생한다.
// 이를 보완하기 위해 추가 25_0423 09:05:48 kku
if UsbConnList_.IndexOf(sDrive) <> -1 then
exit;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Error .. ProcessUSBArrival() .. Check UsbConnList()');
end;
// _Trace('ProcessUSBArrival() .. 2');
// if GetDriveExtent(sDrive).liExtentLength.QuadPart = 0 then
if not DirectoryExists(sDrive) then
begin
if ThdUsbMonRO_ <> nil then
ThdUsbMonRO_.AddEmptyDrive(sDrive)
else if EmDriveList_.IndexOf(sDrive) = -1 then
EmDriveList_.Add(sDrive);
if GetDriveType(PChar(sDrive)) = DRIVE_CDROM then
begin
llSize := 0;
goto LB_ProcCDROM;
end;
exit;
end;
llSize := GetDriveSize(sDrive);
// _Trace('ProcessUSBArrival() .. 3, Size=%d, VName=%s', [llSize, GetVolumeName(sDrive)]);
if llSize <> 0 then
begin
nType := Integer(GetDriveType(PChar(sDrive)));
_Trace('[%s] 드라이브 연결, Drive=%s, Size=%s', [GetDriveTypeToStr(nType), sDrive, ByteSizeToStr(llSize)], 1);
sRecentUsbDrv_ := sDrive;
bCdrom := false;
case nType of
DRIVE_CDROM :
begin
bCdrom := true;
// PopupMessage(TYPE_MSG_PREVENT_CDROM, sDrive + '|' +
// ByteSizeToStr(llSize) + '|' + sFriendlyName + '|CD/DVD|' + sSerial);
//
// SendEventLog(URI_USER_ACTION, PREVENT_CDROM,
// Format('CD/DVD Blocked : Name=%s, Drive=%s (%s), Serial=%s',
// [sFriendlyName, sDrive, ByteSizeToStr(llSize), sSerial]));
// SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_USB,
// Format('USB Connected : Drive=%s, Type=%s',
// [sDriveInfo, sType]));
end;
DRIVE_FIXED,
DRIVE_REMOVABLE :
begin
// if nType = DRIVE_REMOVABLE then // Fixed 도 적용 되도록 롤백 (4005) 25_0917 17:39:41 kku
begin
if ModePolicy.UsbBlockKind = ubkReadOnly then
begin
if ThdUsbMonRO_ = nil then
begin
if IsReadOnlyByWriteProbe(sDrive) <> 1 then
begin
GetDriveDetail(sDrive, @DriveInfo);
SetReadOnly(sDrive, DriveInfo.nDiskNum, false);
end;
end else
ThdUsbMonRO_.AddDrive(sDrive);
end else
if ModePolicy.UsbBlockKind <> ubkBlock then
begin
if IsReadOnlyByWriteProbe(sDrive) = 1 then
begin
_Trace('읽기전용 속성 감지됨 .. Drive=%s', [sDrive], 2);
GetDriveDetail(sDrive, @DriveInfo);
SetReadOnly(sDrive, DriveInfo.nDiskNum, false);
_Trace('읽기전용 속성 해제 .. Drive=%s', [sDrive], 2);
end;
end;
end;
try
if UsbConnList_.IndexOf(sDrive) = -1 then
UsbConnList_.Add(sDrive);
except
// ..
end;
if (FileService_ <> nil) and FileService_.IsWorking then
begin
var bExpUsb: Boolean := false;
if ModePolicy.IgrUsbSerialList.Count > 0 then
begin
GetDriveDetail(sDrive, @DriveInfo);
bExpUsb := ModePolicy.IgrUsbSerialList.IndexOf(DriveInfo.sSerial) <> -1;
end;
FileService_.AddDriveWatch(sDrive, true, bExpUsb);
end;
end;
else _Trace('GetDriveType() .. Unknown .. %d', [nType], 1);
end;
if bCdrom then
begin
LB_ProcCDROM :
DevBlockKind := ModePolicy.CdromBlockKind;
case DevBlockKind of
_ubkPopup,
ubkLog :
begin
var sDriveInfo: String := sDrive; // Format('%s (%s)', [sDrive, ByteSizeToStr(llSize)]);
var sType: String := GetDriveTypeToStr(nType);
if IsDivPopup then
begin
if ModePolicy.CdAllowPopup then
PopupMessage(TYPE_MSG_MONITOR_CDROM, sDriveInfo);
end else begin
if DevBlockKind = _ubkPopup then
PopupMessage(TYPE_MSG_MONITOR_CDROM, sDriveInfo);
end;
sMsg := Format('CD/DVD Connected : Drive=%s', [sDriveInfo]);
if bIsNewApi_ then
begin
GetDriveDetail(sDrive, @DriveInfo);
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := MONITOR_CDROM;
LogInfo.sDevName := DriveInfo.sFriendlyName;
LogInfo.sDevSerial := DriveInfo.sSerial;
LogInfo.sDevClassId := DriveInfo.sClassGuid;
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo, false);
end else
SendEventLog(URI_USER_ACTION, MONITOR_CDROM, sMsg, false);
end;
end;
end else begin
UsbBlockKind := ModePolicy.UsbBlockKind;
case UsbBlockKind of
ubkLog :
begin
var sDriveInfo: String := Format('%s (%s)', [sDrive, ByteSizeToStr(llSize)]);
var sType: String := GetDriveTypeToStr(nType);
if IsDivPopup then
begin
if ModePolicy.UsbAllowPopup then
PopupMessage(TYPE_MSG_MONITOR_USB, sDriveInfo + '|' + sType);
end else begin
if ModePolicy.USBPopup then
PopupMessage(TYPE_MSG_MONITOR_USB, sDriveInfo + '|' + sType);
end;
sMsg := Format('USB Connected : Drive=%s, Type=%s', [sDriveInfo, sType]);
if bIsNewApi_ then
begin
GetDriveDetail(sDrive, @DriveInfo);
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := MONITOR_USB;
LogInfo.sDevName := DriveInfo.sFriendlyName;
LogInfo.sDevSerial := DriveInfo.sSerial;
LogInfo.sDevClassId := DriveInfo.sClassGuid;
LogInfo.sSummary := sMsg;
SendEventLogEx(@LogInfo, false);
end else
SendEventLog(URI_USER_ACTION, MONITOR_USB, sMsg, false);
end;
ubkBlock :
begin
// 바로 차단 시도 추가 25_0929 13:20:09 kku
// _Trace('연결 감지 .. 차단 시도 .. Drive=%s', [sDrive], 2);
// DoEjectUsbDrive(sDrive, nType);
end;
end;
end;
end;
// _Trace('ProcessUSBArrival() .. 4');
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessUSBArrival()');
end;
end;
procedure TManagerService.OnUSBArrival(Sender: TObject; pInfo: PDevBroadcastVolume);
begin
try
ProcessUSBArrival(GetDriveFromMask(pInfo.dwUnitmask));
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnUSBArrival()');
end;
end;
procedure TManagerService.OnUSBQueryRemove(Sender: TObject; sDrive: String; var bAccept: Boolean);
var
i: Integer;
begin
try
i := UsbConnList_.IndexOf(sDrive);
if i <> -1 then
UsbConnList_.Delete(i);
if FileService_ <> nil then
FileService_.DelDriveWatch(sDrive);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnUSBQueryRemove()');
end;
bAccept := true;
end;
procedure TManagerService.ProcessUSBRemove(sDrive: String);
var
i: Integer;
b: Boolean;
begin
// 보안, 가상 드라이브는 OnUSBQueryRemove 이걸 거치지 않아서 추가 25_0423 09:11:42 kku
OnUSBQueryRemove(nil, sDrive, b);
_Trace('USB 드라이브 해제, Drive=%s', [sDrive], 1);
i := IgrEjectDrives_.IndexOf(sDrive);
if i <> -1 then
IgrEjectDrives_.Delete(i);
i := EmDriveList_.IndexOf(sDrive);
if i <> -1 then
EmDriveList_.Delete(i);
if FileService_ <> nil then
FileService_.DelDriveWatch(sDrive);
if ThdUsbMonRO_ <> nil then
ThdUsbMonRO_.DelDrive(sDrive);
end;
procedure TManagerService.OnUSBRemove(Sender: TObject; pInfo: PDevBroadcastVolume);
begin
ProcessUSBRemove(GetDriveFromMask(pInfo.dwUnitmask));
end;
function TManagerService.ProcessPreventBT(pEnt: PBtDevEnt; var bExcept: Boolean): Boolean;
const
EXPT_BLUE_VENDER = ';keychron'; // 기본으로 예외할 벤더사
var
sTemp1, sTemp2: String;
i: Integer;
PvMajorList: TStringList;
begin
Result := false;
if ModePolicy.BlueBlockKind <> dbkBlock then
exit;
bExcept := false;
if not pEnt.dInfo.fConnected then
exit;
sTemp1 := ModePolicy.BlueExceptVender + EXPT_BLUE_VENDER;
sTemp2 := UpperCase(pEnt.dInfo.szName);
if (sTemp1 <> '') and (sTemp2 <> '') then
begin
var VenderList: TStringList;
Guard(VenderList, TStringList.Create);
SplitString(UpperCase(sTemp1), ';', VenderList);
for i := 0 to VenderList.Count - 1 do
if sTemp2.Contains(VenderList[i]) then
begin
bExcept := true;
exit;
end;
end;
Guard(PvMajorList, TStringList.Create);
PvMajorList.CaseSensitive := false;
SplitString(ModePolicy.BlueExcept, ';', PvMajorList);
if PvMajorList.IndexOf(pEnt.sAddress) > -1 then
begin
bExcept := true;
exit;
end;
BtDevTypeToStr(pEnt.dInfo.ulClassofDevice, sTemp1, sTemp2);
if PvMajorList.IndexOf(sTemp1) = -1 then
begin
// BluetoothRemoveDevice() 함수는 단순히 연결을 끊는 것이 아니라,
// 장치 페어링 정보 자체를 시스템에서 제거합니다. 따라서
// 이 함수를 호출하면 해당 장치와의 연결이 끊어지는 것은 물론,
// 페어링 되었던 다른 장치와의 연결 정보에도 영향을 줄 수 있습니다.
Result := BluetoothRemoveDevice(pEnt.dInfo.Address) = 0;
if not Result then
_Trace('Fail .. ProcessPreventBT(), Name="%s", sTemp1=%s', [pEnt.dInfo.szName, sTemp1]);
Result := true; // 차단 대상이면 위 작업과 별개로 장치 차단을 하도록 함 22_0630 09:15:10 kku
exit;
end;
end;
procedure TManagerService.OnBtDevEntNotify(pEnt: PBtDevEnt; csBT: TBTChangeStates; var bPrevent: Boolean);
var
h: HWND;
bExcept, bPopup: Boolean;
sMajor, sMinor, sData, sLog: String;
PO: TPrefModel;
begin
if (csConnected in csBT) or (csAuthenticated in csBT) then
begin
// "장치 추가" 창이 떠있는 경우 팝업 안함 24_0702 15:33:22 kku
// "장치 추가" 창이 떠있는 경우 팝업, 차단, 로깅 안함 25_0930 08:45:26 kku
h := FindWindow('NativeHWNDHost', '장치 추가');
if h = 0 then
h := FindWindow('NativeHWNDHost', 'Add a device');
if h = 0 then
h := FindWindow('ApplicationFrameWindow', '디바이스 추가');
if h = 0 then
h := FindWindow('ApplicationFrameWindow', 'Add a device');
if h <> 0 then
exit;
bExcept := false;
bPrevent := ProcessPreventBT(pEnt, bExcept);
// if bExcept then
// exit;
BtDevTypeToStr(pEnt.dInfo.ulClassofDevice, sMajor, sMinor);
sLog := Format('Name : %s, Type : %s (%s), Address : %s', [pEnt.dInfo.szName, sMajor, sMinor, pEnt.sAddress]);
TTgTrace.T('OnBtDevEntNotify() .. sLog=%s', [sLog], 4);
PO := GetModePolicy;
bPopup := PO.BTPopup;
sData := String(pEnt.dInfo.szName) + '|' + Format('%s (%s)', [sMajor, sMinor]) + '|' + pEnt.sAddress;
if bPrevent then
begin
// FltCtrl_.SetPolicy(DWORD(BDC_BLUETOOTH), DWORD(bPrevent), DWORD(1));
sData := sData + '|PV';
if bPopup then
PopupMessage(TYPE_MSG_PREVENT_BLUETOOTH, sData);
if bIsNewApi_ then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := PREVENT_BLUETOOTH;
LogInfo.sDevName := pEnt.dInfo.szName;
LogInfo.sDevSerial := pEnt.sAddress;
LogInfo.sDevClassId := Format('%s (%s)', [sMajor, sMinor]);
LogInfo.sSummary := 'Blocked : ' + pEnt.dInfo.szName;
SendEventLogEx(@LogInfo);
end else
SendEventLog(URI_USER_ACTION, PREVENT_BLUETOOTH, sLog);
end else begin
// FltCtrl_.SetPolicy(DWORD(BDC_BLUETOOTH), DWORD(bPrevent), DWORD(1));
if PrefModel_.BtConNotiDSec > 0 then
begin
// 일정 시간동안 다시 알림 하지 않도록 기능 보완
if HasDelayProcEntById('BT:' + pEnt.sAddress) then
exit;
AddDelayProcEnt('BT:' + pEnt.sAddress, PrefModel_.BtConNotiDSec);
end;
case PO.BlueBlockKind of
dbkBlock,
dbkLog :
begin
if IsDivPopup then
bPopup := PO.BtAllowPopup;
if bExcept then
sLog := 'Excepted, ' + sLog;
if bPopup then
PopupMessage(TYPE_MSG_PREVENT_BLUETOOTH, sData);
end;
end;
if bIsNewApi_ then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := MONITOR_BLUETOOTH;
LogInfo.sDevName := pEnt.dInfo.szName;
LogInfo.sDevSerial := pEnt.sAddress;
LogInfo.sDevClassId := Format('%s (%s)', [sMajor, sMinor]);
LogInfo.sSummary := 'Detected : ' + pEnt.dInfo.szName;
SendEventLogEx(@LogInfo);
end else
SendEventLog(URI_USER_ACTION, MONITOR_BLUETOOTH, sLog, false);
end;
end;
end;
function ExtrTextFromFile(sPath: String; bIgrImg: Boolean = false): String;
function ExtrTxtData(sSrcPath, sDestPath: String): Boolean;
var
sExe,
sParam: String;
O: ISuperObject;
Opt: TCttSimpleOpt;
nTry: Integer;
Label
LB_Retry;
begin
Result := false;
try
if not FileExists(sSrcPath) then
exit;
sExe := GetRunExePathDir + EXE_KVCTTSCH;
if not FileExists(sExe) then
exit;
Opt.sSrcPath := sSrcPath;
Opt.sDestPath := sDestPath;
Opt.sAssocInfo := '';
sParam := GetRunExePathDir + '$kvcs.dat';
O := SO;
O.I['CSTT'] := Integer(csttExtrSimple);
O.O['SOpt'] := TTgJson.ValueToJsonObject<TCttSimpleOpt>(Opt);
nTry := 0;
LB_Retry :
if SaveJsonObjToFile(O, sParam) then
begin
if ExecuteAppWaitUntilTerminate(sExe, Format('-p "%s"', [sParam]), SW_HIDE, 20000) then
begin
if not FileExists(sDestPath) then
begin
Inc(nTry);
if nTry < 2 then
begin
TTgTrace.T('Fail .. ExtrTextFromFile() .. ExecuteModule', 4);
Sleep(500);
goto LB_Retry;
end else exit;
end;
Result := true;
end else
TTgTrace.T('Fail .. ExtrTextFromFile() .. 1', 4);
end else
TTgTrace.T('Fail .. ExtrTextFromFile() .. 2', 4);
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. ExtrTextFromFile() .. ExtrTxtData()');
end;
end;
var
sExt,
sDestPath: String;
StrList: TStringList;
ss: TStringStream;
begin
Result := '';
sExt := GetFileExt(sPath).ToUpper;
// todo : 압축파일도 내용 추출 추가 필요 25_0410 20:04:49 kku
if Pos(sExt, COMPRESS_EXTS) > 0 then
exit;
if bIgrImg and (Pos(sExt, IMAGE_EXTS) > 0) then
exit;
if Pos(sExt, AIP_EXTS) > 0 then
begin
if IsSupportAIP and IsAipEncryted(sPath) then
exit;
end;
sDestPath := GetRunExePathDir + 'Task\';
if ForceDirectories(sDestPath) then
begin
// 파일 이름에 "문서 출력", "문서출력"이 포함되어 있으면 깨져서 내보내기가 된다... 25_0409 15:33:44 kku
// sDestPath := sDestPath + ExtractFileName(sPath) + '.$kv';
sDestPath := sDestPath + FormatDateTime('yymmddhhnnss', Now) + IntToStr(Length(sPath)) + '.' + GetFileExt(sPath) + '.$kv';
if ExtrTxtData(sPath, sDestPath) then
begin
Result := ExtractTextSafe(sDestPath);
{$IFDEF DEBUG}
if Result = '' then
begin
TTgTrace.T('Fail .. ExtrTextFromFile() .. empty', 4);
exit;
end;
{$ENDIF}
DeleteFile(PChar(sDestPath));
// TTgTrace.T('ExtrTextFromFile() .. Length = %d', [Length(Result)], 4);
end;
end else
TTgTrace.T('Fail .. ExtrTextFromFile() .. not found', 4);
end;
procedure TManagerService.OnUnzipProgress(Sender : TObject; Progress : Byte; var Abort : Boolean);
begin
end;
procedure TManagerService.OnPwdEvent(Sender : TObject; var NewPassword : String);
begin
NewPassword := '';
end;
function TManagerService.HasContentInfo(sMName, sPath: String; aAppType: TCurAppType): Boolean;
var
PatternEntList: TPatternEntList;
nHitLimit, nLimitMB,
nUnzipDepth, nDecompDepth: Integer;
ExtList: TStringList;
function FindContent(var unable : string ; fileNameChk: Boolean; sTgPath: String; var sFounds, sFoundsC: String): Boolean;
var
sExtrTxt,
sSchTxt, sFound: String;
i, nHits,
nOrCnt, nAndCnt,
nHighCnt, nTotalHits: Integer;
begin
try
Result:= False;
unable := '';
sExtrTxt := ExtrTextFromFile(sTgPath);
//검사 불가 파일... kvcttSch.exe를 통해 문서 txt로 변환...
if sExtrTxt = '' then
begin
unable := 'unable to analysis';
exit;
end;
if fileNameChk then
sExtrTxt := 'FileName : ' + ExtractFileName(sTgPath) + #13#10#13#10 + sExtrTxt
else
sExtrTxt := sExtrTxt;
sFounds := '';
sFoundsC := '';
sFound := '';
nTotalHits := 0;
nOrCnt := 0;
nAndCnt := 0;
nHighCnt := 0;
for i := 0 to PatternEntList.Count - 1 do
begin
sSchTxt := PatternEntList[i].GetSearchText;
nHits := TTgPcre.GetMatchValues(sExtrTxt, sSchTxt, sFound);
if nHits > 0 then
begin
if bIsNewApi_ then
begin
if nHits < PatternEntList[i].IfCount then
continue;
if sSchTxt.StartsWith('(?<!\d)\d{2}(01|02|03|04|') then
begin
nHits := 0;
// 주민번호 패턴이라면 검증해준다. 25_0526 15:44:47 kku
var sTemp: String := StringReplace(sFound, '"', '', [rfReplaceAll]);
var HitList: TStringList;
Guard(HitList, TStringList.Create);
SplitString(sTemp, ',', HitList);
var n: Integer;
for n := HitList.Count - 1 downto 0 do
begin
if not IsValidKoreanRegNo(HitList[n]) then
begin
HitList.Delete(n);
continue;
end;
Inc(nHits);
end;
if nHits < PatternEntList[i].IfCount then
continue;
sFound := HitList.CommaText;
end;
if PatternEntList[i].RSeverity = ManagerPattern.rsHigh then
Inc(nHighCnt)
else if PatternEntList[i].IsAnd then
Inc(nAndCnt)
else
Inc(nOrCnt);
end;
Inc(nTotalHits, nHits);
SumString(sFounds, Format('%s(%d)', [CttCodeToStr(PatternEntList[i].Name), nHits]), ',');
SumString(sFoundsC, Format('%s|%s|%d', [PatternEntList[i].Name, sFound, nHits]), RESULT_SEPARATOR);
end;
end;
if nHitLimit <= nTotalHits then
begin
if bIsNewApi_ then
begin
if (nHighCnt = 0) and (PatternEntList.AndCount > 0) then
begin
// AND 갯수가 다르다면 X
if nAndCnt <> PatternEntList.AndCount then
exit;
// OR가 조건으로 있는데 검출된 OR가 없다면 X
if (PatternEntList.AndCount <> PatternEntList.Count) and (nOrCnt = 0) then
exit;
end;
end;
Result := true;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. FindContent()');
end;
end;
function ProcessDecompFile(var unable : string ; fileNameChk: Boolean; sPath, sExportDir: String; var sFounds, sFoundsC: String; sOrgCompPath: String; sParentFile: String = ''): Boolean;
var
i: Integer;
sExt, sUpDirName: String;
begin
Result := False;
unable := '';
try
// 압축파일 처리 22_1201 14:54:18 kku
DeleteDir(sExportDir, true, true);
if ForceDirectories(sExportDir) then
begin
Inc(nDecompDepth);
try
if (nUnzipDepth > 0) and (nUnzipDepth < nDecompDepth) then
exit;
var FList: TStringList;
Guard(FList, TStringList.Create);
try
var ReslutString: string;
ReslutString:= DecompressFile(sPath, sExportDir, OnUnzipProgress, OnPwdEvent);
if ReslutString <> '' then
begin
unable:= ReslutString;
Exit;
end;
ExtrFilesPathFromDir(sExportDir, FList, true);
for i := 0 to FList.Count - 1 do
begin
sExt := GetFileExt(FList[i]).ToUpper;
sUpDirName := StringReplace(ExtractFilePath(FList[i]), sExportDir, '', [rfReplaceAll]);
if sUpDirName <> '' then
sUpDirName := sParentFile + ' > ' + sUpDirName
else
sUpDirName := sParentFile;
if Pos(sExt, COMPRESS_EXTS) > 0 then
begin
Result := ProcessDecompFile(unable, fileNameChk, FList[i],
Format('%s%d\', [sExportDir, nDecompDepth]), sFounds, sFoundsC,
sOrgCompPath, sUpDirName + ' > ' + ExtractFileName(FList[i]));
end else begin
if (ExtList.Count > 0) and (ExtList.IndexOf(sExt) = -1) then
continue;
if CUSTOMER_TYPE = CUSTOMER_LOTTEMART then
begin
case GetFileTypeW_r(FList[i]) of
103, 106 : continue;
// begin
// _Trace('HasContentInfo() .. Fasoo DRM 적용됨2. Path=%s', [FList[i]], 9);
// exit;
// end;
end;
end;
Result := FindContent(unable, fileNameChk, FList[i], sFounds, sFoundsC);
end;
if unable <> '' then
exit;
if Result then
exit;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Unzip');
end;
finally
DeleteDir(sExportDir, true, true);
Dec(nDecompDepth);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessDecompFile()');
end;
end;
var
ModePolify: TPrefModel;
sExt, sExportDir,
sFounds, sFoundsC: String;
REnt: TRecentFnd;
nTO: Integer;
fileNameChk: Boolean;
begin
Result := false;
try
sExt := GetFileExt(sPath).ToUpper;
sFounds := PrefModel_.CfFblkExts;
if sFounds <> '' then
begin
Guard(ExtList, TStringList.Create);
SplitString(UpperCase(sFounds), '|', ExtList);
if ExtList.IndexOf(sExt) > -1 then
begin
Result := true;
REnt.dtReg := Now;
REnt.sMName := sMName;
REnt.sPath := sPath;
REnt.sFounds := 'Blocked by file extension policy.';
REnt.sFoundsC := 'Blocked by file extension policy.';
REnt.bResult := Result;
REnt.curAppType := aAppType;
AddRecentFnd(REnt);
exit;
end;
end;
if CUSTOMER_TYPE = CUSTOMER_LOTTEMART then
begin
case GetFileTypeW_r(sPath) of
103, 106 :
begin
_Trace('HasContentInfo() .. Fasoo DRM 적용됨. Path=%s', [sPath], 9);
exit;
end;
end;
end;
// else
// if CUSTOMER_TYPE = CUSTOMER_CJONS then
// begin
// case GetFileType_r(pData.sDir + pData.sFName) of
// 109, // 이거 뭔지 모르지만 GetFileTypeW_r()로 FED5 암호화파일에서 검출됨.. 25_0217 18:54:27 kku
// 26, 103, 105, 106 : pData.State := resEnc;
// end;
// end;
if CheckSign(sPath, @SIGN_SOFTCAMP_DRM[0], 7) then
begin
_Trace('HasContentInfo() .. SC DRM 적용됨. Path=%s', [sPath], 9);
exit;
end;
if CheckSign(sPath, @SIG_DRM[1], Length(SIG_DRM)) then
begin
_Trace('HasContentInfo() .. BS DRM 적용됨. Path=%s', [sPath], 9);
exit;
end;
ModePolify := GetModePolicy;
OgnRecentFndList; // 일단.. 여기에 놓자 25_0325 09:14:49 kku
if GetRecentFnd(sPath, REnt) then
begin
// WebEx는 동일경로 파일 3분동안 무시 25_0512 10:56:15 kku
if (REnt.sMName <> '') and (CompareText(REnt.sMName, 'CiscoCollabHost.exe') = 0) then
nTO := 180
else
nTO := 2;
if SecondsBetween(REnt.dtReg, Now) <= nTO then
begin
Result := REnt.bResult;
exit;
end;
end;
_Trace('HasContentInfo() .. Path=%s', [sPath], 4);
DelRecentFnd(sPath);
ZeroMemory(@REnt, SizeOf(REnt));
fileNameChk:= True;
Guard(PatternEntList, TPatternEntList.Create);
case aAppType of
catOutlook :
begin
if sOutABPatterns_.Contains('scanoption') then
SetPatternList(sOutABPatterns_, PatternEntList)
else
SetRuleToPtrnList(sOutABPatterns_, PatternEntList, true);
nHitLimit := ModePolify.OutlookAB.ContentFilter.nHitLimit;
end;
catWebb :
begin
if sWebABPatterns_.Contains('scanoption') then
SetPatternList(sWebABPatterns_, PatternEntList)
else
SetRuleToPtrnList(sWebABPatterns_, PatternEntList, true);
nHitLimit := ModePolify.WebbAB.ContentFilter.nHitLimit;
end;
catFquirt :
begin
if BtcontentsFilter_list_.Contains('scanoption') then
SetPatternList(BtcontentsFilter_list_, PatternEntList)
else
SetRuleToPtrnList(BtcontentsFilter_list_, PatternEntList, true);
nHitLimit := 1;
fileNameChk:= ModePolify.IntBtBlockNewFile.fileNameChk;
end;
catLINKENGKM :
begin
if UsbToUsbcontentsFilter_list_.Contains('scanoption') then
SetPatternList(UsbToUsbcontentsFilter_list_, PatternEntList)
else
SetRuleToPtrnList(UsbToUsbcontentsFilter_list_, PatternEntList, true);
nHitLimit := 1;
fileNameChk:= ModePolify.IntUsbToUsbBlockNewFile.fileNameChk;
end;
catUsb :
begin
if UsbcontentsFilter_list_.Contains('scanoption') then
SetPatternList(UsbcontentsFilter_list_, PatternEntList)
else
SetRuleToPtrnList(UsbcontentsFilter_list_, PatternEntList, true);
nHitLimit := 1;
fileNameChk:= ModePolify.IntUsbBlockNewFile.fileNameChk;
end;
catCdrom :
begin
if CdromcontentsFilter_list_.Contains('scanoption') then
SetPatternList(CdromcontentsFilter_list_, PatternEntList)
else
SetRuleToPtrnList(CdromcontentsFilter_list_, PatternEntList, true);
nHitLimit := 1;
fileNameChk:= ModePolify.IntCdromBlockNewFile.fileNameChk;
end;
catMtp :
begin
if MtpcontentsFilter_list_.Contains('scanoption') then
SetPatternList(MtpcontentsFilter_list_, PatternEntList)
else
SetRuleToPtrnList(MtpcontentsFilter_list_, PatternEntList, true);
nHitLimit := 1;
fileNameChk:= ModePolify.IntMtpBlockNewFile.fileNameChk;
end;
else
begin
if sEtcABPatterns_.Contains('scanoption') then
SetPatternList(sEtcABPatterns_, PatternEntList)
else
SetRuleToPtrnList(sEtcABPatterns_, PatternEntList, true);
nHitLimit := ModePolify.EtcAB.ContentFilter.nHitLimit;
end;
end;
var unable : string;
nLimitMB := ModePolify.CfLimitMB;
if (nLimitMB > 0) and (GetFileSize_path(sPath) >= (LONGLONG(nLimitMB) * 1048576)) then
begin
Result:= true;
sFounds := 'File size exceeded.';
sFoundsC := 'File size exceeded.';
end
else if Pos(sExt, COMPRESS_EXTS) > 0 then
begin
Guard(ExtList, TStringList.Create);
case aAppType of
catOutlook : ;
catWebb : SplitString(UpperCase(PrefModel_.WebAbExts), '|', ExtList);
else SplitString(UpperCase(PrefModel_.EtcAbExts), '|', ExtList);
end;
nDecompDepth := 0;
nUnzipDepth := ModePolify.CfZipDepth;
sExportDir := GetRunExePathDir + 'STask\@etr2\';
Result := ProcessDecompFile(unable, fileNameChk, sPath, sExportDir, sFounds, sFoundsC, sPath, ExtractFileName(sPath));
DeleteDir(sExportDir, true, true);
if unable <> '' then
begin
sFounds := unable;
sFoundsC := unable;
Result:= True;
end;
end else
begin
Result := FindContent(unable, fileNameChk, sPath, sFounds, sFoundsC);
if unable <> '' then
begin
sFounds := unable;
sFoundsC := unable;
Result:= True;
end;
end;
REnt.dtReg := Now;
REnt.sMName := sMName;
REnt.sPath := sPath;
REnt.sFounds := sFounds;
REnt.sFoundsC := sFoundsC;
REnt.bResult := Result;
REnt.curAppType := aAppType;
AddRecentFnd(REnt);
_Trace('HasContentInfo() .. OK, (%s), (%s), (%s)', [sPath, sFounds, sFoundsC], 4);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. HasContentInfo()');
end;
end;
function TManagerService.SendPrintImgFiles(sImgPath, sImgOutDir: String; nCollectMax: Integer = 0; aRespaction: TCampnRespaction = crtNone): String;
var
sFName, sCompId: String;
i: Integer;
begin
Result := '';
try
sImgOutDir := IncludeTrailingPathDelimiter(sImgOutDir);
if not ForceDirectories(sImgOutDir) then
exit;
if (GetFileExt(sImgPath).ToUpper = 'PDF') and
(CountFileExt(ExtractFilePath(sImgPath), ['png']) = 0) then
begin
var pdf: EM.PdfiumCore.TPdfDocument;
Guard(pdf, EM.PdfiumCore.TPdfDocument.Create);
pdf.LoadFromFile(sImgPath);
var sOutPath: String := CutFileExt(sImgPath) + '_%.4d.png';
for i := 0 to pdf.PageCount - 1 do
begin
if (nCollectMax > 0) and ((i + 1) > nCollectMax) then
break;
if not PageToPng(pdf.Pages[i], Format(sOutPath, [i + 1]), 150) then
break;
end;
end;
if CountFileExt(ExtractFilePath(sImgPath), ['png']) > 0 then
begin
sFName := StringReplace(CutFileExt(sImgPath), '_0001', '', [rfReplaceAll]); // png에서 추가 분할된건 _0001이 붙을 수 있는데, 제거해준다
i := 1;
while True do
begin
if (nCollectMax > 0) and (i > nCollectMax) then
break;
sImgPath := Format('%s_%.4d.png', [sFName, i]);
if FileExists(sImgPath) then
begin
sFName := FormatDateTime('yymmddhhnnss_', Now) + ExtractFileName(sImgPath);
if CopyFile(PChar(sImgPath), PChar(sImgOutDir + sFName), false) then
begin
sCompId := MakeComponentId(ExtractFileName(sImgPath));
SendFileNor(false, sCompId, 'printLogCollect.do', sImgOutDir + sFName, 0, 20, aRespaction);
SumString(Result, sCompId, ';');
end;
end else exit;
Inc(i);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendPrintImgFiles()');
end;
end;
function EmfToPng(const sEmfPath, sPngPath: string;
nDPI: Integer = 96; aBackColor: TColor = clWhite): Boolean;
var
mf: TMetafile;
bmp: TBitmap;
png: TPngImage;
nW, nH: Integer;
begin
Result := false;
try
if nDPI = 0 then
nDPI := 96;
Guard(mf, TMetafile.Create);
mf.LoadFromFile(sEmfPath);
// TMetafile.MMWidth/MMHeight는 0.01mm 단위
if (mf.MMWidth = 0) or (mf.MMHeight = 0) then
exit;
nW := MulDiv(mf.MMWidth, nDPI, 2540); // 2540 = 25.4(mm) * 100
nH := MulDiv(mf.MMHeight, nDPI, 2540);
Guard(bmp, TBitmap.Create);
bmp.SetSize(nW, nH);
bmp.PixelFormat := pf24bit;
bmp.Canvas.Brush.Color := aBackColor;
bmp.Canvas.FillRect(Rect(0, 0, nW, nH));
// 간단히 벡터를 래스터로 그려 넣기
bmp.Canvas.StretchDraw(Rect(0, 0, nW, nH), mf);
Guard(png, TPngImage.Create);
png.Assign(bmp);
png.SaveToFile(sPngPath);
Result := true;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. EmfToPng()');
end;
end;
// BS1OutlookAddIn_IMPL.pas에 똑같은거 있음. 변경 시 참고
function GetFileToSha1Str_BS1(sPath: String): String;
var
dtCreate, dtModify, dtAccess: TDateTime;
begin
if IsUseFastHash then
begin
if not GetFileDateTime_Local(sPath, dtCreate, dtModify, dtAccess) then
begin
dtCreate := 0;
dtModify := 0;
dtAccess := 0;
end;
sPath := FormatDateTime('yymmddhhnnss+', dtModify) + IntToStr(GetFileSize_path(sPath));
Result := ConvStrToSha1W(sPath);
end else
Result := GetFileToSha1Str(sPath);
end;
function TManagerService.SendPrintEmfFiles(sEmfDir, sImgOutDir: String; nCollectMax: Integer = 0; aRespaction: TCampnRespaction = crtNone): String;
var
sCompId, sImgPath: String;
i: Integer;
EmfList: TStringList;
begin
Result := '';
try
sImgOutDir := IncludeTrailingPathDelimiter(sImgOutDir);
if not ForceDirectories(sImgOutDir) then
exit;
sEmfDir := IncludeTrailingPathDelimiter(sEmfDir);
Guard(EmfList, TStringList.Create);
ExtrFilesFromDir(sEmfDir, EmfList, false, 'em1');
if EmfList.Count > 0 then
begin
EmfList.Sort;
for i := 0 to EmfList.Count - 1 do
begin
if (nCollectMax > 0) and (i >= nCollectMax) then
break;
sImgPath := sImgOutDir + FormatDateTime('yymmddhhnnss_', Now) + Format('%s.png', [CutFileExt(EmfList[i]), i]);
if EmfToPng(sEmfDir + EmfList[i], sImgPath, 200) then
begin
// {$IFDEF DEBUG}
// if i = 0 then
// begin
// CopyFile(PChar(sImgPath), 'C:\Users\kku\Desktop\test.png', false);
// CopyFile(PChar(sEmfDir + EmfList[i]), 'C:\Users\kku\Desktop\test.emf', false);
// end;
// {$ENDIF}
sCompId := MakeComponentId(Format('%.4d', [i]));
SendFileNor(false, sCompId, 'printLogCollect.do', sImgPath, 0, 20, aRespaction);
SumString(Result, sCompId, ';');
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendPrintImgFiles()');
end;
end;
function ExtrTextFromPrintImgFiles(sImgPath: String; aAngle: Extended = 0): String;
var
sFName, sTxt: String;
i, nCnt: Integer;
begin
Result := '';
try
try
if GetFileExt(sImgPath).ToUpper = 'PDF' then
begin
var pdf: EM.PdfiumCore.TPdfDocument;
Guard(pdf, EM.PdfiumCore.TPdfDocument.Create);
pdf.LoadFromFile(sImgPath);
var sOcr: String := GetRunExePathDir + DIR_CONF + EXE_OCR;
var sOutPath: String := CutFileExt(sImgPath) + '_%.4d.png';
// var sTaskDir: String := sOcr[1] + ':\ProgramData\HE\Task\';
// if not ForceDirectories(sTaskDir) then
// begin
// TTgTrace.T('Fail .. ExtrTextFromPrintImgFiles() .. create taskDir ..', 1);
// exit;
// end;
for i := 0 to pdf.PageCount - 1 do
begin
sFName := Format(sOutPath, [i + 1]);
if PageToBitmap(pdf.Pages[i], sFName, 150) then
begin
sTxt := ExtrTextFromImage(sFName, aAngle);
if sTxt <> '' then
SumString(Result, sTxt, #13#10);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 0, i);
end;
end;
end else begin
// TTgTrace.T('ExtrTextFromPrintImgFiles() .. 1');
if FileExists(sImgPath) then
begin
sTxt := ExtrTextFromImage(sImgPath, aAngle);
// if sTxt = '' then
// begin
// TTgTrace.T('ExtrTextFromPrintImgFiles() .. 1 .. Text empty');
// CopyFile(PChar(sImgPath), PChar('c:\test0.' + GetFileExt(sImgPath)), false);
// end;
SumString(Result, sTxt, #13#10);
end;
nCnt := CountFileExt(ExtractFilePath(sImgPath), ['png']);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 5, nCnt);
// TTgTrace.T('ExtrTextFromPrintImgFiles() .. 2');
sFName := CutFileExt(sImgPath);
i := 1;
while True do
begin
sImgPath := Format('%s_%.4d.png', [sFName, i]);
if FileExists(sImgPath) then
begin
sTxt := ExtrTextFromImage(sImgPath, aAngle);
// if sTxt = '' then
// begin
// TTgTrace.T('ExtrTextFromPrintImgFiles() .. 2 .. Text empty');
// CopyFile(PChar(sImgPath), PChar(Format('c:\test%d.', [i]) + GetFileExt(sImgPath)), false);
// end;
SumString(Result, sTxt, #13#10);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 6, i);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 0, i);
end else exit;
Inc(i);
end;
end;
finally
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 0, 0);
if Result <> '' then
begin
case CUSTOMER_TYPE of
CUSTOMER_SHCI,
CUSTOMER_SHSC : Result := StrsReplace(Result,
['01 ', '11 ', '21 ', '31 ', '41 ', '51 ', '61 ', '71 ', '81 ', '91 '],
['01', '11', '21', '31', '41', '51', '61', '71', '81', '91']);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. ExtrTextFromPrintImgFiles()');
end;
end;
function ExtrTextFromPrintEmfFiles(sEmfDir: String; aAngle: Extended = 0): String;
var
sTxt, sImgPath: String;
i: Integer;
EmfList: TStringList;
nDPI: Integer;
begin
Result := '';
try
try
Guard(EmfList, TStringList.Create);
ExtrFilesFromDir(sEmfDir, EmfList, false, 'em1');
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 5, EmfList.Count);
EmfList.Sort;
nDPI := gMgSvc.PrefModel_.PrtDPI;
for i := 0 to EmfList.Count - 1 do
begin
sImgPath := sEmfDir + CutFileExt(EmfList[i]) + '.png';
if EmfToPng(sEmfDir + EmfList[i], sImgPath, nDPI) then
begin
sTxt := ExtrTextFromImage(sImgPath, aAngle);
SumString(Result, sTxt, #13#10);
DeleteFile(PChar(sImgPath));
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 6, i);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 0, i);
end;
end;
finally
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 0, 0);
if Result <> '' then
begin
case CUSTOMER_TYPE of
CUSTOMER_SHCI,
CUSTOMER_SHSC : Result := StrsReplace(Result,
['01 ', '11 ', '21 ', '31 ', '41 ', '51 ', '61 ', '71 ', '81 ', '91 '],
['01', '11', '21', '31', '41', '51', '61', '71', '81', '91']);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. ExtrTextFromPrintImgFiles()');
end;
end;
//procedure TManagerService.SendPrintLog(sCode, sPrtName, sDoc, sExtrTxt,
// sExtrOcrTxt, sDocPath, sThumbIds: String; OVio: ISuperObject);
//var
// O, OSub: ISuperObject;
// sCompId: String;
// sMsg: String;
//begin
// try
// sMsg := Format('Printer : %s, Document : %s', [sPrtName, sDoc]);
//
// _Trace('SendPrintLog > Code=%s, Msg=%s', [sCode, sMsg], 3);
//
// O := SO;
// if sCode = LOGCODE_EVENT_PRINTER then
// O.S['TYP_MSG'] := '@(!)_IC_M'
// else
// O.S['TYP_MSG'] := '@(!)_IC_P';
// O.S['KEY_AGENTID'] := sAgentId_;
// O.S['KEY_EMPNO'] := sEmpNo_;
// O.S['KEY_HOSTNAME'] := sUserName_;
// O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
// O.S['KEY_LOGCODE'] := sCode;
// O.S['DETECTION_DATE'] := O.S['KEY_SUBMITTIME']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
// O.S['KEY_SUMMARY'] := sMsg;
//// O.S['PARENT_LA_ID'] // 상위 이벤트
// O.S['POLICY_ID'] := GetModePolicy.PolicyId;
//// O.S['POLICY_KEY'] // 정책 위반한 경우 (PREVENT, MONITOR), 위반한 정책의 정책 키 값, 수집인 경우 (DEPLOY), 수집 요청 ID
// if GetModePolicy.Print.bCollectOutput then
// begin
// O.S['MESSAGE_BODY'] := sExtrTxt; // 정책 위반한 경우 (PREVENT, MONITOR), 원문 (본문) 컨텐츠, 수집인 경우 (DEPLOY), 수집 결과 내용, 원문 수집 정책이 비활성화인경우 수집하지 않음
// O.S['OCR_BODY'] := sExtrOcrTxt; // 이미지 OCR 추출된 컨텐츠, 원문 수집 정책이 비활성화인 경우 수집하지 않음
// end;
//
// if OVio <> nil then
// O.O['RULE_VIOLATED'] := OVio; // 정책 위반 규칙과 위반 개수. (LIST)
//
// if GetModePolicy.Print.bCollectFile and FileExists(sDocPath) then
// begin
// sCompId := MakeComponentId(ExtractFileName(sDocPath));
// SendFile(sCompId, 'printLogCollect.do', sDocPath);
//
// O.S['COMPONENT_ID'] := sCompId; // 파일 고유값. 에이전트에서 임의 생성. (이벤트간 동일 파일 판단은 서버에서 하겠습니다.)
// O.S['COMPONENT_FILENAME'] := ExtractFileName(sDocPath); // 파일명
// O.S['COMPONENT_PATH'] := ExtractFilePath(sDocPath);// 파일 절대 경로
//// O.S['COMPONENT_METADATA']
//// O.S['COMPONENT_LASTACCESS'] // 파일 최종 접근 일시
// end;
//
// O.S['COMPONENT_THUMBNAIL_ID'] := sThumbIds; // 이미지 미리보기 혹은 이미지가 있는경우, 이미지 파일의 파일 고유값. (출력물의 경우 첫 3장 이미지, 캡쳐 이미지 등), 복수개 허용, ";" 구분
//// O.S['SOURCE_IP'] // 이벤트 발생 시점의 에이전트 IP. 단, 외부에서 수신하는 이벤트의 경우, 발송지의 IP가 되고, DESTINATION_URL이 에이전트 IP가 된다
//// O.S['SOURCE_PORT'] // 송신지 사용 포트
//// O.S['EMAIL_SENDER'] // 메일 발신자
//// O.S['DESTINATION_URL'] // 수신지 URL (혹은 IP)
//// O.S['DESTINATION_PORT'] // 수신지 포트
//// O.S['EMAIL_RECIPIENT'] // 메일 수신자 ; 로 구분
//// O.S['EMAIL_SUBJECT'] // 메일 제목
// O.S['APPLICATION_NAME'] := sPName; // 사용 APP 이름
// O.S['APPLICATION_PATH'] := sPPath;// 사용 APP 절대 경로 (실행 파일 exe의 절대 경로)
// O.S['PRINTER_JOBNAME'] := Job.Document;
// OSub := SO;
// OSub.S['PAGEINFO'] := Format('%d/%d', [PrtInfo.dwTotalPage, PrtInfo.dwTotalPage]);
// OSub.S['COLOR'] := BooleanToStr(PrtInfo.bColor, 'true', 'false');
// OSub.S['WARTERMARK'] := BooleanToStr(bWaterMark, 'true', 'false');
// OSub.S['PAPERINFO'] := PrtInfo.sPaperInfo;
// O.O['PRINTER_METADATA'] := OSub; // '{"PAGEINFO": "2/2", "COLOR": "true", "WARTERMARK": "false"}';
// O.S['REMOVABLE_NAME'] := Job.PrinterName; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 이름
//// O.S['REMOVABLE_DEVICEID'] := aExptInfo.sSerial; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Device ID
//// O.S['DEVICE_TYPE'] := IntToStr(Integer(aExptInfo.ReqDevType)); // 의미 없어서 제외 23_0822 12:40:55 kku
//// O.S['REMOVABLE_CLASSID'] // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Class ID
//// O.S['RESPONSE_INFO'] // 적용된 대응 정보 (DELETE, DRM, POPUP, LOG, EXCEPT 등)
//// O.S['RESPONSE_RESULT'] // 적용된 대응 적용 결과 (true / false / pending / decline)
//// O.S['REQUEST_COMMENT'] := sComment; // 사용자가 기입하는 요청 코멘트
//// O.S['REQUEST_DUEDATE'] := sDueDate; // 사용자가 기입하는 예외 기간 (언제 까지. 최종일)
//// O.S['REQUEST_TARGET'] := IntToStr(nTarget); // 사용자가 기입하는 예외 대상 (0 - 해당 pc, 1 - 해당 사용자, 2 - 해당 부서, 3-전체)
//
// gMgSvc.EventLog.Push(O.AsJSon);
// except
// on E: Exception do
// ETgException.TraceException(Self, E, 'Fail .. SendEventLog()');
// end;
//end;
procedure SetPrtJobFromHelperApp(aJob: TPrtJobInfo; dwCmd: DWORD);
var
sHpExe,
sPrtName: String;
begin
// sPrtName := aJob.PrinterName;
// if sPrtName = '' then
// begin
// var PrtInfo: TPrtJobDevInfo;
// aJob.GetJobDevInfo(PrtInfo);
// sPrtName := PrtInfo.sPtrName;
// end;
//
// var hPrt: THandle := 0;
// if OpenPrinter(PChar(sPrtName), hPrt, nil) then
// SetJob(hPrt, aJob.ID, 0, nil, dwCmd);
//
// if (dwCmd = JOB_CONTROL_PAUSE) and ((aJob.Status and JOB_STATUS_SPOOLING) <> 0) then
// aJob.IsCustomPause := true;
//
// exit;
try
TTgTrace.T('SetPrtJobFromHelperApp() .. cmd=%d', [dwCmd], 1);
sHpExe := GetRunExePathDir + DIR_CONF + EXE_HP;
if FileExists(sHpExe) then
begin
sPrtName := aJob.PrinterName;
if sPrtName = '' then
begin
var PrtInfo: TPrtJobDevInfo;
aJob.GetJobDevInfo(PrtInfo);
sPrtName := PrtInfo.sPtrName;
end;
{$IFDEF DEBUG}
ExecuteApp(sHpExe, Format('-pjob "%s" -c %d -j %d', [sPrtName, dwCmd, aJob.ID]), SW_SHOWNORMAL);
{$ELSE}
ExecuteAppAsUser('explorer.exe', sHpExe, Format('-pjob "%s" -c %d -j %d', [sPrtName, dwCmd, aJob.ID]), SW_SHOWNORMAL);
{$ENDIF}
if not aJob.WorkEnd and (dwCmd = JOB_CONTROL_PAUSE) and ((aJob.Status and JOB_STATUS_SPOOLING) <> 0) then
begin
aJob.IsCustomPause := true;
TTgTrace.T('SetPrtJobFromHelperApp() .. cmd=%d .. CustomPause', [dwCmd], 1);
end;
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail SetPrtJobFromHelperApp()');
end;
end;
procedure TManagerService.OnPtrJobNotify(Sender: TThdPrtSpoolWatch; Job: TPrtJobInfo);
begin
try
if Job.WorkEnd then
exit;
if not Job.IsCustomPause and Job.IsSpooling then
begin
if bIgrPrtPause_ then
exit;
if (Job.Document <> '') and Job.Document.Contains(' *BSOne') then
begin
// 보안 출력중이면 그냥 통과 25_0522 16:22:54 kku
// exit;
end else begin
// SetPrtJobFromHelperApp(Job, JOB_CONTROL_PAUSE);
Job.PausePrtJob;
end;
exit;
end;
if Job.IsCustomPause then
begin
if (Job.Document <> '') and Job.Document.Contains(' *BSOne') then
begin
// SetPrtJobFromHelperApp(Job, JOB_CONTROL_RESUME);
Job.ResumePrtJob;
exit;
end;
if ThdPrintWork_ <> nil then
begin
if ThdPrintWork_.HasJob(Job) then
exit;
if ThdPrintWork_.IsWorking then
begin
// _Trace('보안출력 중 새로운 출력 감지 .. 차단. Printer=%s, Doc=%s', [Job.PrinterName, Job.Document], 2);
// CancelJob;
// HEC에서 스풀을 두번 생성해서 처리하는 현상 확인됨. 25_0714 09:31:43 kku
// 이유는 모르겠는데 복합기 드라이버에서 그렇게 처리하는거 같음 (롯데 캐논)
_Trace('보안출력 중 새로운 출력 감지 .. 무시. Printer=%s, Doc=%s', [Job.PrinterName, Job.Document], 2);
exit;
end else
if not Job.WorkEnd then
begin
Job.Wnd := GetForegroundWindow;
// Job.PID := GetProcessPIDFromWndHandle(Job.Wnd);
// Job.PName := GetProcessNameByPid(Job.PID);
ThdPrintWork_.AddJob(Job);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnPtrJobNotify()');
end;
end;
procedure TManagerService.OnCapAppNotify(aSender: TThdProcessWatch; pEnt: PPwEnt; aKind: TProcessWatchKind);
var
CapAppMonKind: TCapAppMonKind;
PO: TPrefModel;
begin
try
case aKind of
pwkUnknown : _Trace('OnCapAppNotify() .. Unknown');
pwkInit,
pwkExecute :
begin
if CapAppList_.IndexOf(pEnt.sPName) <> -1 then
begin
PO := GetModePolicy;
if bForceScreenCapAppBlock_ then
begin
if IsNewApi then
begin
var IgrAppList: TStringList;
Guard(IgrAppList, TStringList.Create);
IgrAppList.CaseSensitive := false;
SplitString(PO.IgrCaptureApps, '|', IgrAppList);
if IgrAppList.IndexOf(pEnt.sPName) = -1 then
begin
TerminateProcessByPid(pEnt.dwPid);
if PO.IsNotiBCA then
PopupMessage(TYPE_MSG_PREVENT_CAPAPP, pEnt.sPName + '|PV');
SendEventLog(URI_USER_ACTION, PREVENT_CAPTURE_APP, 'Software Blocked : ' + pEnt.sPName);
end else
SendEventLog(URI_USER_ACTION, MONITOR_CAPTURE_APP, 'Software Detected : ' + pEnt.sPName, false);
end else begin
TerminateProcessByPid(pEnt.dwPid);
if PO.IsNotiBCA then
PopupMessage(TYPE_MSG_PREVENT_CAPAPP, pEnt.sPName + '|PV');
SendEventLog(URI_USER_ACTION, PREVENT_CAPTURE_APP, 'Software Blocked : ' + pEnt.sPName);
end;
exit;
end;
CapAppMonKind := PO.CapAppMonKind;
case CapAppMonKind of
camBlockAll :
begin
TerminateProcessByPid(pEnt.dwPid);
if PO.IsNotiBCA then
PopupMessage(TYPE_MSG_PREVENT_CAPAPP, pEnt.sPName + '|PV');
SendEventLog(URI_USER_ACTION, PREVENT_CAPTURE_APP, 'Software Blocked : ' + pEnt.sPName);
end;
camIncAllow :
begin
var IgrAppList: TStringList;
Guard(IgrAppList, TStringList.Create);
IgrAppList.CaseSensitive := false;
SplitString(PO.IgrCaptureApps, '|', IgrAppList);
if IgrAppList.IndexOf(pEnt.sPName) = -1 then
begin
TerminateProcessByPid(pEnt.dwPid);
if PO.IsNotiBCA then
PopupMessage(TYPE_MSG_PREVENT_CAPAPP, pEnt.sPName + '|PV');
SendEventLog(URI_USER_ACTION, PREVENT_CAPTURE_APP, 'Software Blocked : ' + pEnt.sPName);
end else
SendEventLog(URI_USER_ACTION, MONITOR_CAPTURE_APP, 'Software Detected : ' + pEnt.sPName, false);
end;
camLog,
camPopup :
begin
if (CapAppMonKind = camPopup) or PO.IsNotiBCA then
PopupMessage(TYPE_MSG_PREVENT_CAPAPP, pEnt.sPName);
SendEventLog(URI_USER_ACTION, MONITOR_CAPTURE_APP, 'Software Detected : ' + pEnt.sPName, false);
end;
end;
end;
end;
pwkTerminated : ;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnCapAppNotify()');
end;
end;
procedure TManagerService.OnBlockAppNotify(aSender: TThdProcessWatch; pEnt: PPwEnt; aKind: TProcessWatchKind);
var
PO: TPrefModel;
bBlock,
bChkBlackApp: Boolean;
dtNow: TDateTime;
sPath: String;
procedure SendMonAppLog(bExecute: Boolean);
var
LogInfo: TLogInfo;
begin
ZeroMemory(@LogInfo, SizeOf(LogInfo));
sPath := GetProcessPathByPid(pEnt.dwPid);
LogInfo.sAppName := pEnt.sPName;
LogInfo.sAppPath := ExtractFilePath(sPath);
LogInfo.sPath := sPath;
if bExecute then
begin
LogInfo.sCode := MONITOR_SOFTWARE;//EXECUTE_APP;
LogInfo.sSummary := pEnt.sPName + ' executed.';
end else begin
LogInfo.sCode := MONITOR_SOFTWARE;//TERMINATE_APP;
LogInfo.sSummary := pEnt.sPName + ' terminated.';
end;
gMgSvc.SendEventLogEx(@LogInfo, false);
if ModePolicy.IsMonAppNoti then
begin
var O: ISuperObject;
O := SO;
O.S['PName'] := pEnt.sPName;
O.B['E'] := bExecute;
PopupMessage(TYPE_MSG_MONITOR_APP, O.AsJSon);
end;
end;
begin
try
case aKind of
pwkUnknown : _Trace('OnBlockAppNotify() .. Unknown');
pwkInit,
pwkExecute :
begin
if aKind <> pwkInit then
begin
_Trace('APP 실행됨. PName=%s', [pEnt.sPName], 100);
if bIsMonApp_ and (MonAppList_.IndexOf(pEnt.sPName) <> -1) then
SendMonAppLog(true);
end;
bBlock := bIsBlockApp_ and (BlockAppList_.IndexOf(pEnt.sPName) <> -1);
if not bBlock and (BlockAppWList_.Count > 0) then
begin
var i: Integer;
for i := 0 to BlockAppWList_.Count - 1 do
begin
if MatchesMask(pEnt.sPName, BlockAppWList_[i]) then
begin
bBlock := true;
break;
end;
end;
end;
if bBlock then
begin
PO := GetModePolicy;
bChkBlackApp := true;
dtNow := Now;
// for Test
// gMgSvc.ModePolicy.AppBlackDateB := StrToDateDef('2022-08-22', 0);
// if gMgSvc.ModePolicy.AppBlackDateB <> 0 then
// gMgSvc.ModePolicy.AppBlackDateB := AppendTime(gMgSvc.ModePolicy.AppBlackDateB, 0, 0, 0, 0);
// gMgSvc.ModePolicy.AppBlackDateE := StrToDateDef('2022-08-23', 0);
// if gMgSvc.ModePolicy.AppBlackDateE <> 0 then
// gMgSvc.ModePolicy.AppBlackDateE := AppendTime(gMgSvc.ModePolicy.AppBlackDateE, 23, 59, 59, 0);
if PO.IsAppBlackDate then
begin
bChkBlackApp := (CompareDateTime(PO.AppBlackDateB, dtNow) = -1 ) and
(CompareDateTime(PO.AppBlackDateE, dtNow) = 1);
end;
if bChkBlackApp and PO.IsAppBlackTime then
begin
var wHour, wMin, wSec, wMSec: WORD;
DecodeTime(dtNow, wHour, wMin, wSec, wMSec);
if PO.AppBlackTimeB <= PO.AppBlackTimeE then
bChkBlackApp := (PO.AppBlackTimeB <= wHour) and (PO.AppBlackTimeE >= wHour)
else
bChkBlackApp := (PO.AppBlackTimeB <= wHour) or (PO.AppBlackTimeE > wHour);
end;
if bChkBlackApp then
begin
sPath := GetProcessPathByPid(pEnt.dwPid);
if not PO.IsBlockAppLog then
TerminateProcessByName(pEnt.sPName);
if PO.IsBlockAppNotice then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_BLACKAPP, pEnt.sPName + BooleanToStr(PO.IsBlockAppLog, '', '|PV'));
if gMgSvc.IsNewApi then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sAppName := pEnt.sPName;
LogInfo.sAppPath := ExtractFilePath(sPath);
LogInfo.sPath := sPath;
if PO.IsBlockAppLog then
begin
LogInfo.sCode := MONITOR_SOFTWARE;
LogInfo.sSummary := 'Software Execute : ' + pEnt.sPName;
end else begin
LogInfo.sCode := LOGCODE_PREVENT_SOFTWARE;
LogInfo.sSummary := 'Software Blocked : ' + pEnt.sPName;
end;
gMgSvc.SendEventLogEx(@LogInfo, not PO.IsBlockAppLog);
end else
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_SOFTWARE, 'Software Blocked : ' + pEnt.sPName);
_Trace('Block App .. Name="%s"', [pEnt.sPName]);
end;
end;
end;
pwkTerminated :
begin
_Trace('APP 종료됨. PName=%s', [pEnt.sPName], 100);
// if bIsMonApp_ and (MonAppList_.IndexOf(pEnt.sPName) <> -1) then
// SendMonAppLog(false);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnBlockAppNotify()');
end;
end;
function TManagerService.RecentUserSid: String;
begin
if sRecentUserSid_ = '' then
sRecentUserSid_ := GetRegRecentUserSid;
Result := sRecentUserSid_;
if not ExistsKey(HKEY_USERS, sRecentUserSid_) then
begin
_Trace('현재 사용자 Sid를 찾을 수 없음 .. Sid=%s', [sRecentUserSid_], 2);
sRecentUserSid_ := '';
end;
end;
procedure TManagerService.ChangeDestinationUrl;
begin
try
Inc(nDestSvrIdx_);
if (nDestSvrIdx_ < 99999) and (CUSTOMER_TYPE = CUSTOMER_HDENG) then // 초기화 직후에는 무시 25_1016 19:24:49 kku
begin
// 보안모드 조건이 IP조건이고, PC가 내부망 IP를 사용중일때 내부망만 접속 시도,
// 내부망 IP가 아니면 DMZ 만 접속 시도록하도록 기능 추가
// 보안모드 조건이 IP 조건이 아닐 경우 기존 처럼 동작 25_0911 20:31:18 kku
if PrefModel.VpnMethod.Contains('ip') then
begin
if bIsRouterOn_ then
nDestSvrIdx_ := 0 // 내부망
else
nDestSvrIdx_ := 1; // DMZ망
end;
end;
if nDestSvrIdx_ >= ServerUrlList_.Count then
nDestSvrIdx_ := 0;
sDestSvrUrl_ := ServerUrlList_[nDestSvrIdx_];
if (Pos(sDestSvrUrl_, 'https://') <> 1) and (Pos(sDestSvrUrl_, 'http://') <> 1) then
begin
sDestSvrUrl_ := StrsReplace(sDestSvrUrl_, ['/'], '');
var sIp: String;
var nPort: Integer;
if ExtractIPPort(sDestSvrUrl_, sIp, nPort) then
sDestSvrUrl_ := Format('https://%s:%d/agentLogRequests.do', [sIp, nPort])
else if IsValidIP(sDestSvrUrl_) then
sDestSvrUrl_ := Format('https://%s:443/agentLogRequests.do', [sDestSvrUrl_])
else
sDestSvrUrl_ := ServerUrlList_[nDestSvrIdx_];
end;
sDestIPort_ := StringReplace(sDestSvrUrl_, 'agentLogRequest.do', '', [rfReplaceAll]);
sDestIPort_ := StringReplace(sDestIPort_, 'agentLogRequests.do', '', [rfReplaceAll]);
// bSSLCouldNotLoad_ := false;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ChangeDestinationUrl()');
end;
end;
procedure TManagerService.DoClipboardUpdate;
begin
bDoCbUpdate_ := true;
end;
// 삭제, 업데이트를 위해 안전한 종료를 위해 추가 23_0331 09:14:05 kku
procedure TManagerService.StopService;
begin
ThdTaskTimer_.StopTimerThread;
ThdStatusTimer_.StopTimerThread;
if MgHook_ <> nil then
FreeAndNil(MgHook_);
if FltCtrl_ <> nil then
FltCtrl_.Cleanup;
end;
procedure TManagerService.SetRouterOn(bVal: Boolean);
begin
bIsRouterOn_ := bVal;
end;
procedure TManagerService.SetVpnNicOn(bVal: Boolean);
begin
bIsVpnNicOn_ := bVal;
end;
procedure TManagerService.SetPatchUpdate(bIsUptoDate: Boolean);
var
nTerm: Integer;
begin
// 네트워크 통신이 안되는 상태에서 sData가 무조건 'true'가 된다.
// 그래서 보완 하기 위해 서버와 접속중이 아니거나
// 접속 후 5초 이내는 결과를 무시한다. 22_1025 17:39:57 kku
// (접속 후 5초 안에 나온 결과값은 무조건 'true' 때문에 무시해야한다.)
// MG.exe에서 HE.exe로 업데이트 기능 옮긴 후 15초에서 5초로 변경 22_1124 15:36:18 kku
if (dtConnected_ = 0) or
(bIsUptoDate and (SecondsBetween(Now, dtConnected_) < 5)) then exit;
if bIsPatchUptoDate_ <> bIsUptoDate then
begin
nTerm := GetOsPatchCheckTerm;
if nTerm > 0 then
begin
// 1주에 한번 패치체크 추가 22_0609 08:52:21 kku
if (AgentModel_.LastOsPatchDT = 0) or
(DaysBetween(AgentModel_.LastOsPatchDT, Now) >= nTerm) then
begin
bIsPatchUptoDate_ := bIsUptoDate;
if bIsPatchUptoDate_ then
begin
AgentModel_.LastOsPatchDT := Now;
AgentModel_.Save;
end;
end else
bIsPatchUptoDate_ := true;
end else
bIsPatchUptoDate_ := bIsUptoDate;
end;
end;
procedure TManagerService.SetServiceAvailable(bVal: Boolean);
begin
bIsServiceAvailable_ := bVal;
end;
procedure TManagerService.SetTemporaryConn(bVal: Boolean);
begin
Lock;
try
if bIsTemporaryConn_ = bVal then
exit;
bIsTemporaryConn_ := bVal;
finally
Unlock;
end;
if bVal then
begin
if VulService_ <> nil then
VulService_.CallPopup(true);
dwTempConnBegin_ := GetTickCount;
PopupMessage(TYPE_MSG_PREVENT_TEMPCONN);
end else
dwTempConnBegin_ := 0;
end;
//procedure TManagerService.SetNexgVpnRegistered(bVal: Boolean);
//begin
// bIsNexgVpnRegistered_ := bVal;
//end;
procedure TManagerService.SetNetworkPrevent(bVal: Boolean);
begin
bIsNetworkPrevent_ := bVal;
end;
procedure TManagerService.SetNetworkPreventVal(sVal: String);
begin
sNetworkPreventValue_ := sVal;
end;
procedure TManagerService.SetNetworkExceptVal(sVal: String);
begin
sNetworkExceptValue_ := sVal;
end;
procedure TManagerService.SetNetworkPreventType(sVal: String);
begin
sNetworkPreventType_ := sVal;
end;
procedure TManagerService.SetExtraPort(sVal: String);
begin
sExtraPort_ := sVal;
end;
procedure TManagerService.SetRecentPrintDocName(sVal: String);
begin
sRecentPrintDocName_ := sVal;
end;
procedure TManagerService.AddPrtHookJob(aO: ISuperObject);
begin
try
_Trace('AddPrtHookJob() ..', 2);
if aO.S['DocName'] = '' then
exit;
if aO.S['PName'] = '' then
exit;
if ThdPrintWork_ <> nil then
ThdPrintWork_.AddHookJob(aO.S['PName'], aO.S['PrtName'], aO.S['DocName'], aO.S['PrtDocId'], aO.I['PID']);
_Trace('AddPrtHookJob() .. OK', 2);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. AddPrtHookJob()');
end;
end;
procedure TManagerService.UpdateAgentInfo;
begin
sEmpNo_ := AgentModel_.EmpNo;
// sVpnId_ := AgentModel_.VpnInfo;
sAgentId_ := GetAgentId(sEmpNo_);
sUName_ := AgentModel_.UName;
sEmail_ := AgentModel_.Email;
sDeptName_ := AgentModel_.DeptName;
end;
procedure TManagerService.SendEventLog(sUri, sCode, sMsg: String; bPrevent: Boolean = true);
var
O: ISuperObject;
dt: TDateTime;
begin
try
// 접속상태 체크하지 않음 22_0908 07:47:44 kku
// 이렇게 하면 서버 통신 안될때 굉장히 버벅된다 (알림팝업등)
// if not Connected then
// Sleep(3000);
if sAgentId_ = '' then
exit;
if ThdEvent_ = nil then
exit;
_Trace('SendEventLog > Uri=%s, Code=%s, Msg=%s', [sUri, sCode, sMsg], 3);
dt := Now;
O := SO;
if bIsNewApi_ then
begin
if bPrevent then
O.S['TYP_MSG'] := '@(!)_IC_P'
else
O.S['TYP_MSG'] := '@(!)_IC_M';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['KEY_ACCOUNT'] := sAccount_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_LOGCODE'] := sCode;
O.S['DETECTION_DATE'] := O.S['KEY_SUBMITTIME']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['detectionDate'] := O.S['key_submitTime']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['KEY_SUMMARY'] := sMsg;
// O.S['PARENT_LA_ID'] // 상위 이벤트
O.S['POLICY_ID'] := GetModePolicy.PolicyId;
// O.['attachList'] := ''
// O.S['POLICY_KEY'] // 정책 위반한 경우 (PREVENT, MONITOR), 위반한 정책의 정책 키 값, 수집인 경우 (DEPLOY), 수집 요청 ID
// O.S['MESSAGE_BODY'] // 정책 위반한 경우 (PREVENT, MONITOR), 원문 (본문) 컨텐츠, 수집인 경우 (DEPLOY), 수집 결과 내용, 원문 수집 정책이 비활성화인경우 수집하지 않음
// O.S['OCR_BODY'] // 이미지 OCR 추출된 컨텐츠, 원문 수집 정책이 비활성화인 경우 수집하지 않음
// O.S['RULE_VIOLATED'] // 정책 위반 규칙과 위반 개수. (LIST)
// O.S['COMPONENT_ID'] // 파일 고유값. 에이전트에서 임의 생성. (이벤트간 동일 파일 판단은 서버에서 하겠습니다.)
// O.S['COMPONENT_FILENAME'] // 파일명
// O.S['COMPONENT_PATH'] // 파일 절대 경로
// O.S['COMPONENT_METADATA']
// O.S['COMPONENT_LASTACCESS'] // 파일 최종 접근 일시
// O.S['COMPONENT_THUMBNAIL_ID'] // 이미지 미리보기 혹은 이미지가 있는경우, 이미지 파일의 파일 고유값. (출력물의 경우 첫 3장 이미지, 캡쳐 이미지 등), 복수개 허용, ";" 구분
// O.S['SOURCE_IP'] // 이벤트 발생 시점의 에이전트 IP. 단, 외부에서 수신하는 이벤트의 경우, 발송지의 IP가 되고, DESTINATION_URL이 에이전트 IP가 된다
// O.S['SOURCE_PORT'] // 송신지 사용 포트
// O.S['EMAIL_SENDER'] // 메일 발신자
// O.S['DESTINATION_URL'] // 수신지 URL (혹은 IP)
// O.S['DESTINATION_PORT'] // 수신지 포트
// O.S['EMAIL_RECIPIENT'] // 메일 수신자 ; 로 구분
// O.S['EMAIL_SUBJECT'] // 메일 제목
// O.S['APPLICATION_NAME'] // 사용 APP 이름
// O.S['APPLICATION_PATH'] // 사용 APP 절대 경로 (실행 파일 exe의 절대 경로)
// O.S['PRINTER_JOBNAME'] // 프린터 잡 이름
// O.S['PRINTER_METADATA']
// O.S['REMOVABLE_NAME'] // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 이름
// O.S['REMOVABLE_DEVICEID'] // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Device ID
// O.S['REMOVABLE_CLASSID'] // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Class ID
// O.S['RESPONSE_INFO'] // 적용된 대응 정보 (DELETE, DRM, POPUP, LOG, EXCEPT 등)
// O.S['RESPONSE_RESULT'] // 적용된 대응 적용 결과 (true / false / pending / decline)
// O.S['REQUEST_COMMENT'] // 사용자가 기입하는 요청 코멘트
// O.S['REQUEST_DUEDATE'] // 사용자가 기입하는 예외 기간 (언제 까지. 최종일)
// O.S['REQUEST_TARGET'] // 사용자가 기입하는 예외 대상 (0 - 해당 pc, 1 - 해당 사용자, 2 - 해당 부서, 3-전체)
end else begin
O.S['MODEL_ID'] := sAgentId_;
O.S['TOCSG_LA_IFNAME'] := sUri;
O.S['TOCSG_LA_ID'] := sAgentId_;
O.S['TOCSG_LA_EMPID'] := sEmpNo_;
O.S['TOCSG_LA_CODE'] := sCode;
O.S['TOCSG_LA_DATA'] := sMsg;
if IsUseHostNameOnly then
O.S['TOCSG_LA_HOSTNAME'] := sComName_
else
O.S['TOCSG_LA_HOSTNAME'] := sUserName_;
O.S['TOCSG_LA_LASTCONNDATE'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
if NicService_ <> nil then
begin
O.S['TOCSG_LA_MACADDR'] := NicService_.GetIP;
O.S['TOCSG_LA_REMOTEIP'] := NicService_.GetMAC;
end else begin
O.S['TOCSG_LA_MACADDR'] := 'ip';
O.S['TOCSG_LA_REMOTEIP'] := 'mac';
end;
end;
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLog()');
end;
end;
procedure TManagerService.SendEventLogEx(pInfo: PLogInfo; bPrevent: Boolean = true; dtLog: TDateTime = 0);
var
PO: TPrefModel;
O: ISuperObject;
dt: TDateTime;
begin
try
// 접속상태 체크하지 않음 22_0908 07:47:44 kku
// 이렇게 하면 서버 통신 안될때 굉장히 버벅된다 (알림팝업등)
// if not Connected then
// Sleep(3000);
if sAgentId_ = '' then
exit;
if ThdEvent_ = nil then
exit;
_Trace('SendEventLogEx > Code=%s, Summary=%s', [pInfo.sCode, pInfo.sSummary], 3);
PO := GetModePolicy;
if (pInfo.sCode = LOGCODE_PREVENT_FILEMONITOR) and PO.FileMonNoLog then
exit;
if dtLog <> 0 then
dt := dtLog
else
dt := Now;
O := SO;
if bIsNewApi_ then
begin
if bPrevent then
O.S['TYP_MSG'] := '@(!)_IC_P'
else
O.S['TYP_MSG'] := '@(!)_IC_M';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['KEY_ACCOUNT'] := sAccount_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_LOGCODE'] := pInfo.sCode;
O.S['DETECTION_DATE'] := O.S['KEY_SUBMITTIME']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['detectionDate'] := O.S['key_submitTime']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
if pInfo.sLogId <> '' then
O.S['logId'] := pInfo.sLogId;
if pInfo.sSummary <> '' then
begin
if (PrefModel_.TextLimit > 0) and (Length(pInfo.sSummary) > PrefModel_.TextLimit) then
SetLength(pInfo.sSummary, PrefModel_.TextLimit);
O.S['KEY_SUMMARY'] := pInfo.sSummary;
end;
// O.S['PARENT_LA_ID'] // 상위 이벤트
O.S['POLICY_ID'] := PO.PolicyId;
// O.S['POLICY_KEY'] // 정책 위반한 경우 (PREVENT, MONITOR), 위반한 정책의 정책 키 값, 수집인 경우 (DEPLOY), 수집 요청 ID
if pInfo.sBody <> '' then
begin
if (PrefModel_.TextLimit > 0) and (Length(pInfo.sBody) > PrefModel_.TextLimit) then
SetLength(pInfo.sBody, PrefModel_.TextLimit);
O.S['MESSAGE_BODY'] := pInfo.sBody; // 정책 위반한 경우 (PREVENT, MONITOR), 원문 (본문) 컨텐츠, 수집인 경우 (DEPLOY), 수집 결과 내용, 원문 수집 정책이 비활성화인경우 수집하지 않음
end;
if pInfo.sOcrBody <> '' then
begin
if (PrefModel_.TextLimit > 0) and (Length(pInfo.sOcrBody) > PrefModel_.TextLimit) then
SetLength(pInfo.sOcrBody, PrefModel_.TextLimit);
O.S['OCR_BODY'] := pInfo.sOcrBody; // 이미지 OCR 추출된 컨텐츠, 원문 수집 정책이 비활성화인 경우 수집하지 않음
end;
if pInfo.OVio <> nil then
O.O['RULE_VIOLATED'] := pInfo.OVio; // 정책 위반 규칙과 위반 개수. (LIST)
if pInfo.sFileCompId <> '' then
O.S['COMPONENT_ID'] := pInfo.sFileCompId; // 파일 고유값. 에이전트에서 임의 생성. (이벤트간 동일 파일 판단은 서버에서 하겠습니다.)
if pInfo.sPath <> '' then
begin
O.S['COMPONENT_FILENAME'] := ExtractFileName(pInfo.sPath); // 파일명
O.S['COMPONENT_PATH'] := ExtractFilePath(pInfo.sPath); // 파일 절대 경로
if FileExists(pInfo.sPath) then
begin
var dtCreate, dtModify, dtAccess: TDateTime;
GetFileDateTime_Local(pInfo.sPath, dtCreate, dtModify, dtAccess);
var dwAttr: DWORD := GetFileAttributes(PChar(pInfo.sPath));
var OTemp: ISuperObject := SO;
OTemp.S['FILESIZE'] := IntToStr(GetFileSize_path(pInfo.sPath));
OTemp.S['LASTMODIFIED'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtModify);
if dwAttr <> DWORD(-1) then
OTemp.S['READONLY'] := BooleanToStr((dwAttr and FILE_ATTRIBUTE_READONLY) <> 0, 'true', 'false');
if dwAttr <> DWORD(-1) then
OTemp.S['HIDDEN'] := BooleanToStr((dwAttr and FILE_ATTRIBUTE_HIDDEN) <> 0, 'true', 'false');
// OTemp.S['AUTHOR'] // {만든 이}
// OTemp.S['LASTUSER'] // {마지막으로 저장한 사람}
// OTemp.S['FILETYPE'] // {컨텐츠 타입}
// OTemp.S['FILECLS'] // {컨텐츠 형식}
// OTemp.S['PASSWORD'] // {암호적용여부}
// OTemp.S['ENCRYPTED'] := BooleanToStr(pInfo.bDrm, 'true', 'false');
// OTemp.S['CORRUPT'] // {깨진파일/정상파일여부}
case StrToIntDef(pInfo.sCode, 0) of
52605, // EXECUTE_APP
52606, // TERMINATE_APP
50022, // LOGCODE_PREVENT_SOFTWARE
50503, // MONITOR_SOFTWARE
50009, // LOGCODE_PREVENT_FILEIO
50026 : // LOGCODE_PREVENT_FILEMONITOR
begin
var sExt: String := GetFileExt(pInfo.sPath);
if (sExt <> '') and (sExt.ToUpper = 'EXE') then
begin
var FI: TTgFileInfo;
Guard(FI, TTgFileInfo.Create(pInfo.sPath));
if FI.Version <> '' then OTemp.S['version'] := FI.Version;
if FI.InternalName <> '' then OTemp.S['internalName'] := FI.InternalName;
if FI.LegalCopyright <> '' then OTemp.S['copyright'] := FI.LegalCopyright;
if FI.LegalTradeMarks <> '' then OTemp.S['tradeMarks'] := FI.LegalTradeMarks;
if FI.OriginalFileName <> '' then OTemp.S['originalName'] := FI.OriginalFileName;
if FI.ProductName <> '' then OTemp.S['productName'] := FI.ProductName;
if FI.Comments <> '' then OTemp.S['comments'] := FI.Comments;
if FI.Company <> '' then OTemp.S['company'] := FI.Company;
if FI.Description <> '' then OTemp.S['description'] := FI.Description;
end else begin
var i: Integer;
var StrList: TStringList;
Guard(StrList, TStringList.Create);
GetFileProp_all(pInfo.sPath, StrList, true);
for i := 0 to StrList.Count - 1 do
OTemp.S[StrsReplace(StrList.KeyNames[i], [' '], '_')] := StrList.ValueFromIndex[i];
end;
end;
end;
O.O['COMPONENT_METADATA'] := OTemp;
O.S['COMPONENT_LASTACCESS'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtAccess);
end;
end;
// O.S['COMPONENT_METADATA']
// O.S['COMPONENT_LASTACCESS'] // 파일 최종 접근 일시
if pInfo.sThumbIds <> '' then
begin
if pInfo.sCode = MONITOR_appScreenRec then
begin
var OA: ISuperObject := SO(pInfo.sThumbIds);
O.O['attachList'] := OA;
end else
O.S['COMPONENT_THUMBNAIL_ID'] := pInfo.sThumbIds; // 이미지 미리보기 혹은 이미지가 있는경우, 이미지 파일의 파일 고유값. (출력물의 경우 첫 3장 이미지, 캡쳐 이미지 등), 복수개 허용, ";" 구분
end;
if NicService_ <> nil then
O.S['SOURCE_IP'] := NicService_.GetIP // 이벤트 발생 시점의 에이전트 IP. 단, 외부에서 수신하는 이벤트의 경우, 발송지의 IP가 되고, DESTINATION_URL이 에이전트 IP가 된다
else
O.S['SOURCE_IP'] := 'src_ip';
// O.S['SOURCE_PORT'] // 송신지 사용 포트
if pInfo.sSender <> '' then
O.S['EMAIL_SENDER'] := pInfo.sSender; // 메일 발신자
if pInfo.sDestIpUrl <> '' then
begin
if Length(pInfo.sDestIpUrl) > 512 then
SetLength(pInfo.sDestIpUrl, 512);
O.S['DESTINATION_URL'] := pInfo.sDestIpUrl; // 수신지 URL (혹은 IP)
end;
if pInfo.sDestPort <> '' then
O.S['DESTINATION_PORT'] := pInfo.sDestPort; // 수신지 포트
if pInfo.sRecipient <> '' then
O.S['EMAIL_RECIPIENT'] := pInfo.sRecipient; // 메일 수신자 ; 로 구분
if pInfo.sSubject <> '' then
O.S['EMAIL_SUBJECT'] := pInfo.sSubject; // 메일 제목
if pInfo.sAppName <> '' then
O.S['APPLICATION_NAME'] := pInfo.sAppName; // 사용 APP 이름
if pInfo.sAppPath <> '' then
O.S['APPLICATION_PATH'] := pInfo.sAppPath; // 사용 APP 절대 경로 (실행 파일 exe의 절대 경로)
// O.S['PRINTER_JOBNAME'] // 프린터 잡 이름
// O.S['PRINTER_METADATA']
if pInfo.sDevName <> '' then
begin
if (PrefModel_.TextLimit > 0) and (Length(pInfo.sDevName) > PrefModel_.TextLimit) then
SetLength(pInfo.sDevName, PrefModel_.TextLimit);
O.S['REMOVABLE_NAME'] := pInfo.sDevName; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 이름
end;
if pInfo.sDevSerial <> '' then
O.S['REMOVABLE_DEVICEID'] := pInfo.sDevSerial; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Device ID
if pInfo.sDevClassId <> '' then
O.S['REMOVABLE_CLASSID'] := pInfo.sDevClassId; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Class ID
if pInfo.sResInfo <> '' then
O.S['RESPONSE_INFO'] := pInfo.sResInfo; // 적용된 대응 정보 (DELETE, DRM, POPUP, LOG, EXCEPT 등)
// O.S['RESPONSE_RESULT'] // 적용된 대응 적용 결과 (true / false / pending / decline)
if pInfo.sComment <> '' then
O.S['REQUEST_COMMENT'] := pInfo.sComment; // 사용자가 기입하는 요청 코멘트
// O.S['REQUEST_DUEDATE'] // 사용자가 기입하는 예외 기간 (언제 까지. 최종일)
// O.S['REQUEST_TARGET'] // 사용자가 기입하는 예외 대상 (0 - 해당 pc, 1 - 해당 사용자, 2 - 해당 부서, 3-전체)
end;
if pInfo.sActionId <> '' then
O.S['actionGroupId'] := pInfo.sActionId;
// {$IFDEF DEBUG} SaveJsonObjToFile(O, 'c:\lx.json'); {$ENDIF}
// ThdEvent_.Push(O.AsString);
// JSON 포맷으로 잘 변환되서 보내도록 보완 24_0716 10:32:32 kku
ThdEvent_.Push(O.AsJSon);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLog()');
end;
end;
procedure TManagerService.SendEventLogEx(sCode, sSummary: String; bPrevent: Boolean = true; dtLog: TDateTime = 0);
var
LogInfo: TLogInfo;
begin
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := sCode;
LogInfo.sSummary := sSummary;
SendEventLogEx(@LogInfo, bPrevent, dtLog);
end;
function TManagerService.SendApproval(nType: Integer; pData: Pointer; bUpFileCnt: Integer = 0): String;
var
O: ISuperObject;
begin
Result := '';
try
O := SO;
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['type'] := IntToStr(nType);
case nType of
0, 13 : // 출력물 결재 요청 (0), 사후 결재 (13)
begin
with PPrtEnt(pData)^ do
begin
O.S['taskId'] := sId;
O.S['data1'] := sVioText;
O.S['data2'] := BooleanToStr(sFPath <> '', sFPath, WInfo.sDocName);
O.S['data3'] := sThumbIds;
O.S['data4'] := sText;
O.S['data5'] := sOcrText;
end;
end;
1, 5, 6, 7 : // USB, MTP, Bluetooth, CD/DVD 예외 요청
begin
var OInfo: ISuperObject := SO;
OInfo.S['deviceName'] := PReqDevExceptInfo(pData).sDevName;
OInfo.S['deviceId'] := PReqDevExceptInfo(pData).sSerial;
O.S['data2'] := OInfo.AsJSon;
end;
2 : // 브라우저 접근 차단 예외 요청
begin
O.S['data2'] := String(pData);
end;
3 : // DRM 해제 요청
begin
O.S['data2'] := ISuperObject(pData).AsJSon;
end;
4, 9 : // 파일 반출 요청
begin
O.S['data2'] := PReqDevExceptInfo(pData).sSerial;
if GetFileExt(PReqDevExceptInfo(pData).sDevName).ToUpper <> 'EXE' then
O.S['originEvtUrl'] := PReqDevExceptInfo(pData).sDevName
else
O.S['originEvtApp'] := PReqDevExceptInfo(pData).sDevName;
end;
12 : // 캡처 APP 예외 결재
begin
var OInfo: ISuperObject := SO;
OInfo.S['appName'] := PReqDevExceptInfo(pData).sSerial;
O.S['data2'] := OInfo.AsJSon;
end;
end;
// ss.SaveToFile('c:\reqData.json');
if bUpFileCnt > 0 then
Result := GetPostData(Format('approvalRequest.do?reqUploadUrlCnt=%d', [bUpFileCnt]), O.AsJSon, '0')
else
Result := GetPostData('approvalRequest.do', O.AsJSon, '0');
if Result.Contains('error') then
begin
// 오류 반환됨 24_1002 14:32:08 kku
_Trace('Error .. SendApprovalPrint() .. Msg="%s"', [Result]);
Result := '';
end else begin
try
O := SO(Result);
except
// ..
O := nil;
end;
if O = nil then
begin
_Trace('Error2 .. SendApprovalPrint() .. Msg="%s"', [Result]);
Result := '';
end else
if bUpFileCnt = 0 then
begin
Result := O.S['url'];
if (Result <> '') and (Result[1] = '/') then
Delete(Result, 1, 1);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendApprovalPrint()');
end;
end;
procedure TManagerService.SendAgreeInfo;
var
// HTTP: TIdHTTP;
// SSL: TIdSSLIOHandlerSocketOpenSSL;
// ss: TStringStream;
O: ISuperObject;
begin
try
// Guard(SSL, TIdSSLIOHandlerSocketOpenSSL.Create(nil));
// SSL.SSLOptions.Method := sslvSSLv23;
// SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
//
// Guard(HTTP, TIdHTTP.Create(nil));
// HTTP.IOHandler := SSL;
// with HTTP do
// begin
// HandleRedirects := true;
// Request.Clear;
// Request.UserAgent := 'Mozilla/5.0';
// Request.ContentType := 'application/xml';
// Request.AcceptCharSet := 'UTF-8';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
// Request.CustomHeaders.Values['requestType'] := '1';
// HTTPOptions := HTTP.HTTPOptions + [hoForceEncodeParams];
// ConnectTimeout := 5000;
// ReadTimeout := 5000;
// end;
AgentModel_.EulaDT := Now;
AgentModel_.Save;
O := SO;
O.S['TYP_MSG'] := '@(!)_LOG1';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_LOGCODE'] := SYSEVT_AGREEINFO;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['DETECTION_DATE'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', AgentModel_.EulaDT);
ThdEvent_.Push(O.AsString);
// Guard(ss, TStringStream.Create(O.AsJSon, TEncoding.UTF8));
// Result := HTTP.Post(sDestIPort_ + 'eventLog.do', ss);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendAgreeInfo()');
end;
end;
function TManagerService.GetApprovalUrl(sReqType: String): String;
var
O: ISuperObject;
begin
Result := '';
try
O := SO;
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['type'] := '0';
Result := GetPostData('approvalRequest.do', O.AsJSon, sReqType);
if Result.Contains('error') then
begin
_Trace('Error .. GetApprovalUrl() .. Msg="%s"', [Result]);
Result := '';
end else begin
try
O := SO(Result);
except
// ..
O := nil;
end;
if O = nil then
begin
_Trace('Error2 .. GetApprovalUrl() .. Msg="%s"', [Result]);
Result := '';
end else
Result := O.S['url'];
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetApprovalUrl()');
end;
end;
function TManagerService.GetRegPerInfoUrl: String;
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
O: ISuperObject;
begin
Result := '';
try
O := SO;
O.S['agentId'] := sAgentId_;
Result := GetPostData('empEditUrlRequest.do', O.AsJSon);
if Result.Contains('error') then
begin
_Trace('Error .. GetRegPerInfoUrl() .. Msg="%s"', [Result]);
Result := '';
end else begin
try
O := SO(Result);
except
// ..
O := nil;
end;
if O = nil then
begin
_Trace('Error2 .. GetRegPerInfoUrl() .. Msg="%s"', [Result]);
Result := '';
end else
Result := O.S['url'];
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetRegPerInfoUrl()');
end;
end;
function TManagerService.GetPostData(sUrl, sData: String; sReqType: String = ''): String;
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
ss: TStringStream;
begin
Result := '';
try
if sUrl = '' then
exit;
if sUrl[1] = '/' then
Delete(sUrl, 1, 1);
Guard(SSL, TIdSSLIOHandlerSocketOpenSSL.Create(nil));
SSL.SSLOptions.Method := sslvSSLv23;
SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
Guard(HTTP, TIdHTTP.Create(nil));
HTTP.IOHandler := SSL;
with HTTP do
begin
HandleRedirects := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/xml';
Request.AcceptCharSet := 'UTF-8';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
Request.Connection := 'close';
HTTPOptions := HTTPOptions - [hoKeepOrigProtocol];
if sReqType <> '' then
Request.CustomHeaders.Values['requestType'] := sReqType;
HTTPOptions := HTTP.HTTPOptions + [hoForceEncodeParams];
ConnectTimeout := 5000;
ReadTimeout := 5000;
end;
Guard(ss, TStringStream.Create(sData, TEncoding.UTF8));
Result := HTTP.Post(sDestIPort_ + sUrl, ss);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetPostData()');
end;
end;
procedure TManagerService.SendRequest(sCode: String; aExptInfo: TReqDevExceptInfo; sComment, sBeginDate, sDueDate: String; nTarget: Integer; sMsg: String);
var
O: ISuperObject;
dt: TDateTime;
begin
try
if sAgentId_ = '' then
exit;
_Trace('SendRequest > Code=%s, Msg=%s', [sCode, sMsg], 3);
dt := Now;
O := SO;
if CUSTOMER_TYPE = CUSTOMER_TMAP then
begin
case aExptInfo.ReqDevType of
rdtUsbDrive : O.S['TYP_MSG'] := '@(!)_REQ_TMAP_1';
// rdtMtp : ;
// rdtBluetooth : ;
// rdtCdrom : ;
rdtDrm :
begin
// 별도 처리 23_1212 16:44:34 kku
O.S['TYP_MSG'] := '@(!)_REQ_TMAP_6';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_SUMMARY'] := sMsg;
O.S['MESSAGE_BODY'] := aExptInfo.sDevName;
O.S['REQUEST_COMMENT'] := sComment;
O.S['REQUEST_TARGET'] := '0'; // 0 : 요청 PC, 요청 사용자, 부서, 전체, nTarget
O.S['REQUEST_TYPE'] := 'INTERNAL-DRM';
O.S['REQUEST_DUEDATE'] := O.S['KEY_SUBMITTIME'];
O.S['REQUEST_DUEDATE_U'] := O.S['key_submitTime'];
ThdEvent_.Push(O.AsString);
exit;
end;
rdtPrintWater :
begin
// 별도 처리 23_1212 16:44:34 kku
O.S['TYP_MSG'] := '@(!)_REQ_TMAP_7';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_SUMMARY'] := sMsg;
O.S['MESSAGE_BODY'] := aExptInfo.sDevName;
O.S['REQUEST_COMMENT'] := sComment;
O.S['REQUEST_TARGET'] := '0'; // 0 : 요청 PC, 요청 사용자, 부서, 전체, nTarget
O.S['REQUEST_TYPE'] := 'INTERNAL-WATER';
O.S['REQUEST_DUEDATE'] := O.S['KEY_SUBMITTIME'];
O.S['REQUEST_DUEDATE_U'] := O.S['key_submitTime'];
ThdEvent_.Push(O.AsString);
exit;
end;
rdtPiFile :
begin
O.S['TYP_MSG'] := '@(!)_REQ_EXPT_PI';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_SUMMARY'] := sMsg;
O.S['MESSAGE_BODY'] := aExptInfo.sDevName;
O.S['REQUEST_COMMENT'] := sComment;
O.S['REQUEST_TARGET'] := '0'; // 0 : 요청 PC, 요청 사용자, 부서, 전체, nTarget
O.S['REQUEST_TYPE'] := 'INTERNAL-PI'; // INTERNAL-WATER
O.S['REQUEST_DUEDATE'] := O.S['KEY_SUBMITTIME'];
O.S['REQUEST_DUEDATE_U'] := O.S['key_submitTime'];
ThdEvent_.Push(O.AsString);
exit;
end;
else
O.S['TYP_MSG'] := '@(!)_REQ';
end;
end else
O.S['TYP_MSG'] := '@(!)_REQ';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_LOGCODE'] := sCode;
O.S['DETECTION_DATE'] := O.S['KEY_SUBMITTIME']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['detectionDate'] := O.S['key_submitTime']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['KEY_SUMMARY'] := sMsg;
// O.S['PARENT_LA_ID'] // 상위 이벤트
O.S['POLICY_ID'] := GetModePolicy.PolicyId;
// O.S['POLICY_KEY'] // 정책 위반한 경우 (PREVENT, MONITOR), 위반한 정책의 정책 키 값, 수집인 경우 (DEPLOY), 수집 요청 ID
// O.S['MESSAGE_BODY'] // 정책 위반한 경우 (PREVENT, MONITOR), 원문 (본문) 컨텐츠, 수집인 경우 (DEPLOY), 수집 결과 내용, 원문 수집 정책이 비활성화인경우 수집하지 않음
// O.S['OCR_BODY'] // 이미지 OCR 추출된 컨텐츠, 원문 수집 정책이 비활성화인 경우 수집하지 않음
// O.S['RULE_VIOLATED'] // 정책 위반 규칙과 위반 개수. (LIST)
// O.S['COMPONENT_ID'] // 파일 고유값. 에이전트에서 임의 생성. (이벤트간 동일 파일 판단은 서버에서 하겠습니다.)
// O.S['COMPONENT_FILENAME'] // 파일명
// O.S['COMPONENT_PATH'] // 파일 절대 경로
// O.S['COMPONENT_METADATA']
// O.S['COMPONENT_LASTACCESS'] // 파일 최종 접근 일시
// O.S['COMPONENT_THUMBNAIL_ID'] // 이미지 미리보기 혹은 이미지가 있는경우, 이미지 파일의 파일 고유값. (출력물의 경우 첫 3장 이미지, 캡쳐 이미지 등), 복수개 허용, ";" 구분
// O.S['SOURCE_IP'] // 이벤트 발생 시점의 에이전트 IP. 단, 외부에서 수신하는 이벤트의 경우, 발송지의 IP가 되고, DESTINATION_URL이 에이전트 IP가 된다
// O.S['SOURCE_PORT'] // 송신지 사용 포트
// O.S['EMAIL_SENDER'] // 메일 발신자
// O.S['DESTINATION_URL'] // 수신지 URL (혹은 IP)
// O.S['DESTINATION_PORT'] // 수신지 포트
// O.S['EMAIL_RECIPIENT'] // 메일 수신자 ; 로 구분
// O.S['EMAIL_SUBJECT'] // 메일 제목
// O.S['APPLICATION_NAME'] // 사용 APP 이름
// O.S['APPLICATION_PATH'] // 사용 APP 절대 경로 (실행 파일 exe의 절대 경로)
// O.S['PRINTER_JOBNAME'] // 프린터 잡 이름
// O.S['PRINTER_METADATA']
O.S['REMOVABLE_NAME'] := aExptInfo.sDevName; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 이름
O.S['REMOVABLE_DEVICEID'] := aExptInfo.sSerial; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Device ID
// O.S['DEVICE_TYPE'] := IntToStr(Integer(aExptInfo.ReqDevType)); // 의미 없어서 제외 23_0822 12:40:55 kku
// O.S['REMOVABLE_CLASSID'] // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 Class ID
// O.S['RESPONSE_INFO'] // 적용된 대응 정보 (DELETE, DRM, POPUP, LOG, EXCEPT 등)
// O.S['RESPONSE_RESULT'] // 적용된 대응 적용 결과 (true / false / pending / decline)
O.S['REQUEST_COMMENT'] := sComment; // 사용자가 기입하는 요청 코멘트
O.S['REQUEST_STARTDATE'] := sBeginDate; // 시작일 추가 24_1205 10:20:44 kku
O.S['REQUEST_DUEDATE'] := sDueDate; // 사용자가 기입하는 예외 기간 (언제 까지. 최종일)
O.S['REQUEST_TARGET'] := IntToStr(nTarget); // 사용자가 기입하는 예외 대상 (0 - 해당 pc, 1 - 해당 사용자, 2 - 해당 부서, 3 - 전체)
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLog()');
end;
end;
function GetSendFileJsonObj(sCompId, sApi, sPath: String; nMinMB, nLimitMB: Integer; aRespaction: TCampnRespaction; nRespDelaySec: Integer): ISuperObject;
begin
try
Result := SO;
Result.S['TYP_MSG'] := '@(!)_SF';
Result.S['CompId'] := sCompId;
Result.S['Path'] := sPath;
Result.S['API'] := sApi;
Result.I['MSize'] := nMinMB;
Result.I['LSize'] := nLimitMB;
Result.I['DSec'] := nRespDelaySec;
if aRespaction <> crtNone then
Result.I['AFW'] := Integer(aRespaction);
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. GetSendFileJsonObj()');
end;
end;
procedure TManagerService.SendFile(var LogInfo: TLogInfo; sApi, sPath: String; nMinMB: Integer = 0; nLimitMB: Integer = 50; aRespaction: TCampnRespaction = crtNone; nRespDelaySec: Integer = 0);
var
O: ISuperObject;
bSendBin: Boolean;
sCompId, sData: String;
begin
try
bSendBin := false;
sCompId := LogInfo.sFileCompId;
if sApi = 'quarantineLogCollect.do' then
begin
// 원본 수집 시 대용량 업로드 방식으로 변경 25_1208 15:46:14 kku
LogInfo.sLogId := StrsReplace(TGUID.NewGuid.ToString, ['{', '}'], '');
sData := GetPostData(Format('aapi/files/bin/issue?logId=%s&type=incOrgFile&fileName=%s', [LogInfo.sLogId, UrlEncodeUTF8(ExtractFileName(sPath))]), '');
try
if sData <> '' then
begin
var ORst: ISuperObject := SO(sData);
if ORst.S['uploadUrl'] <> '' then
begin
LogInfo.sFileCompId := ORst.S['fileId'];
sCompId := 'file';
sApi := ORst.S['uploadUrl'];
bSendBin := true;
end;
end;
except
//
end;
end;
if (sApi <> '') and (sApi[1] = '/') then
Delete(sApi, 1, 1);
O := GetSendFileJsonObj(sCompId, sApi, sPath, nMinMB, nLimitMB, aRespaction, nRespDelaySec);
if bSendBin then
O.B['SB'] := true;
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendFile()');
end;
end;
procedure TManagerService.SendFileNor(bSendBin: Boolean; sCompId, sApi, sPath: String; nMinMB: Integer = 0; nLimitMB: Integer = 50; aRespaction: TCampnRespaction = crtNone; nRespDelaySec: Integer = 0);
var
O: ISuperObject;
begin
try
if (sApi <> '') and (sApi[1] = '/') then
Delete(sApi, 1, 1);
O := GetSendFileJsonObj(sCompId, sApi, sPath, nMinMB, nLimitMB, aRespaction, nRespDelaySec);
if bSendBin or sApi.Contains('/bin?') then
O.B['SB'] := true;
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendFileNor()');
end;
end;
procedure TManagerService.SendCttSchProgInfo(aProg: TCttSchProg);
var
O: ISuperObject;
begin
try
// if not Connected then
// Sleep(3000);
if sAgentId_ = '' then
exit;
O := SO;
O.S['KEY_SCAN_ID'] := aProg.sScanId;
O.S['KEY_SCAN_TASK_ID'] := aProg.sTaskId;
O.S['KEY_SCAN_AGENT_ID'] := sAgentId_;
if IsUseHostNameOnly then
O.S['KEY_SCAN_HOSTNAME'] := sComName_
else
O.S['KEY_SCAN_HOSTNAME'] := sUserName_;
O.S['KEY_SCAN_EMP_ID'] := sEmpNo_;
O.S['KEY_SCAN_STATUS'] := aProg.sStatus;
O.S['KEY_SCAN_TOTAL'] := IntToStr(aProg.llTotal);
O.S['KEY_SCAN_COMPLETED'] := IntToStr(aProg.llProc);
O.S['KEY_SCAN_STARTTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', aProg.dtStart);
O.S['KEY_SCAN_RESULT'] := aProg.sResult;
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLogCttSchProg()');
end;
end;
procedure TManagerService.SendCampnProgInfo(aProg: TCttSchProg);
begin
try
if pProcCampn_ = nil then
exit;
MgCampn_.SendCampaignProgress(pProcCampn_, aProg);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendCampnProgInfo()');
end;
end;
procedure TManagerService.SendCttSchDetailInfo(sTaskId: String; pResult: PSchResult; nProcType: Integer);
var
O: ISuperObject;
dtCreate, dtModify, dtAccess: TDateTime;
sPath: String;
nPos: Integer;
begin
try
// if not Connected then
// Sleep(3000);
if sAgentId_ = '' then
exit;
sPath := pResult.sPath;
nPos := Pos(' > ', sPath);
if nPos > 0 then
SetLength(sPath, nPos - 1);
GetFileDateTime_Local(sPath, dtCreate, dtModify, dtAccess);
O := SO;
O.S['KEY_SCAN_TASK_ID'] := sTaskId;
if IsUseHostNameOnly then
O.S['KEY_SCAN_HOSTNAME'] := sComName_
else
O.S['KEY_SCAN_HOSTNAME'] := sUserName_;
O.S['KEY_SCAN_EMP_ID'] := sEmpNo_;
O.S['KEY_SCAN_PATH'] := pResult.sPath;
O.S['KEY_SCAN_FILENAME'] := pResult.sFName; // ExtractFileName(pResult.sPath);
O.S['KEY_SCAN_VIOLATE_TEXT'] := pResult.sResultStr;
O.S['KEY_SCAN_VIOLATE_POLICY'] := pResult.sSchName;
O.S['KEY_SCAN_VIOLATE_COUNT'] := IntToStr(pResult.nHitCnt);
if pResult.bDrm then
O.S['KEY_SCAN_ENCRYPT'] := 'true';
case nProcType of
1 : O.S['KEY_SCAN_FORCE_ENC'] := 'true';
2 : O.S['KEY_SCAN_FORCE_DEL'] := 'true';
3 : O.S['KEY_SCAN_EXCEPT'] := 'true';
end;
O.S['KEY_SCAN_LASTMODIFIED'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtModify);
O.S['KEY_SCAN_LASTACCESS'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtAccess);
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLogCttSchDetail()');
end;
end;
procedure TManagerService.SendAppInstInfo;
var
O: ISuperObject;
InstList: TTgInstAppList;
sPath,
sData: String;
i, nPos: Integer;
begin
try
if IsNewServerOnly then
exit;
// if not Connected then
// Sleep(3000);
if sAgentId_ = '' then
exit;
// _Trace('SendAppInstInfo() ..');
_Trace('SendAppInstInfo(-) .. OldTime=%s, NewTime=%s', [DateTimeToStr(dtSoftInstTick_), DateTimeToStr(Now)]);
Guard(InstList, TTgInstAppList.Create);
InstList.UpdateInstAppList;
sData := '';
for i := 0 to InstList.Count - 1 do
with InstList[i]^ do
begin
sPath := StringReplace(sIconPath, '"', '', [rfReplaceAll]);
nPos := Pos('.EXE', UpperCase(sPath));
if nPos > 0 then
begin
SetLength(sPath, nPos + 3);
if not FileExists(sPath) then
sPath := '';
end else
sPath := '';
SumString(sData, Format('appName:%s|updateTime:%s|procName:%s|ver:%s|company:%s',
[sName, FormatDateTime('yyyy-mm-dd hh:nn:ss', dtInst), ExtractFileName(sPath), sVersion, sPublisher]), '*');
end;
sPath := GetRunExePathDir + 'AppInstInfo.txt';
if FileExists(sPath) then
DeleteFile(PChar(sPath));
if CUSTOMER_TYPE = CUSTOMER_DEV then
WriteLnFileEndUTF8(sPath, sData);
O := SO;
O.S['KEY_APP_AGENT_ID'] := sAgentId_;
if IsUseHostNameOnly then
O.S['KEY_APP_HOSTNAME'] := sComName_
else
O.S['KEY_APP_HOSTNAME'] := sUserName_;
O.S['KEY_APP_EMP_ID'] := sEmpNo_;
O.S['KEY_APP_LIST'] := sData;
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendAppInstInfo()');
end;
end;
function TManagerService.SendHwInfo: Boolean;
var
O, OA, OInfo: ISuperObject;
ItemList: TStringList;
i: Integer;
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
ss: TStringStream;
sResult: String;
begin
{$IFDEF DEBUG}
Result := true;
bIsSendHWInfo_ := true;
exit;
{$ENDIF}
Result := false;
try
Guard(ItemList, TStringList.Create);
O := SO;
O.S['cpu'] := WMI_GetCpuInfo;
O.S['mainboard'] := WMI_GetBaseboardInfo;
O.S['biosVer'] := WMI_GetBiosVersion;
ItemList.CommaText := StringReplace(WMI_GetVideoController, ', ', ',', [rfReplaceAll]);
OA := TSuperObject.Create(stArray);
for i := 0 to ItemList.Count - 1 do
OA.AsArray.Add(ItemList[i]);
O.O['graphics'] := OA;
O.S['memory'] := ByteSizeToStr(WMI_GetMemory);
ItemList.CommaText := StringReplace(WMI_GetMonitor, ', ', ',', [rfReplaceAll]);
OA := TSuperObject.Create(stArray);
for i := 0 to ItemList.Count - 1 do
OA.AsArray.Add(ItemList[i]);
O.O['monitors'] := OA;
OA := TSuperObject.Create(stArray);
Guard(ItemList, TStringList.Create);
ItemList.CommaText := GetDrivesFromMask(GetLogicalDrives);
for i := 0 to ItemList.Count - 1 do
begin
OInfo := SO;
OInfo.S['path'] := ItemList[i];
OInfo.I['sizeMb'] := GetDriveSize(ItemList[i]);
OA.AsArray.Add(OInfo);
end;
O.O['drives'] := OA;
O.S['osInstallDate'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', WMI_GetOSInstallDateTime);
Guard(SSL, TIdSSLIOHandlerSocketOpenSSL.Create(nil));
SSL.SSLOptions.Method := sslvSSLv23;
SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
Guard(HTTP, TIdHTTP.Create(nil));
HTTP.IOHandler := SSL;
with HTTP do
begin
HandleRedirects := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/xml';
Request.AcceptCharSet := 'UTF-8';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
Request.Connection := 'close';
HTTPOptions := HTTPOptions - [hoKeepOrigProtocol];
Request.CustomHeaders.Values['requestType'] := '0';
HTTPOptions := HTTP.HTTPOptions + [hoForceEncodeParams];
ConnectTimeout := 5000;
ReadTimeout := 5000;
end;
Guard(ss, TStringStream.Create(O.AsJSon, TEncoding.UTF8));
sResult := sDestIPort_ + Format('api/agents/%s/hw-info?agentMode=1', [sAgentId_]);
sResult := HTTP.Put(sResult, ss);
// var StrList: TStringList;
// Guard(StrList, TStringList.Create);
// StrList.Text := sResult;
// StrList.SaveToFile('c:\test.html', TEncoding.UTF8);
Result := (HTTP.ResponseCode = 200) and (sResult = '{"result":"success"}');
bIsSendHWInfo_ := Result;
except
on E: EIdHTTPProtocolException do
begin
if E.ErrorCode = 304 then
begin
bIsSendHWInfo_ := true;
exit;
end;
end;
on E: Exception do
begin
bIsSendHWInfo_ := true;
ETgException.TraceException(Self, E, 'Fail .. SendHwInfo()');
end;
end;
end;
function TManagerService.DirectSendEventLog(sUri, sCode, sMsg: String; bPrevent: Boolean = false): Boolean;
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
ss: TStringStream;
O: ISuperObject;
sReq,
sResult: String;
dt: TDateTime;
begin
Result := false;
try
// Uninstall 이벤트 처리처럼 바로 처리해야 할 경우... 보통 없을듯 22_0624 09:11:06 kku
Guard(SSL, TIdSSLIOHandlerSocketOpenSSL.Create(nil));
SSL.SSLOptions.Method := sslvSSLv23;
SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
Guard(HTTP, TIdHTTP.Create(nil));
HTTP.IOHandler := SSL;
with HTTP do
begin
HandleRedirects := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/xml';
Request.AcceptCharSet := 'UTF-8';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
Request.Connection := 'close';
HTTPOptions := HTTPOptions - [hoKeepOrigProtocol];
HTTPOptions := HTTP.HTTPOptions + [hoForceEncodeParams];
ConnectTimeout := 5000;
ReadTimeout := 5000;
end;
dt := Now;
O := SO;
if bIsNewApi_ then
begin
if bPrevent then
sReq := 'prevent'
else
sReq := 'monitor';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['KEY_ACCOUNT'] := sAccount_;
if IsUseHostNameOnly then
O.S['KEY_HOSTNAME'] := sComName_
else
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_LOGCODE'] := sCode;
O.S['DETECTION_DATE'] := O.S['KEY_SUBMITTIME']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['detectionDate'] := O.S['key_submitTime']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['KEY_SUMMARY'] := sMsg;
O.S['POLICY_ID'] := GetModePolicy.PolicyId;
end else begin
O.S['MODEL_ID'] := sAgentId_;
O.S['TOCSG_LA_IFNAME'] := sUri;
O.S['TOCSG_LA_ID'] := sAgentId_;
O.S['TOCSG_LA_EMPID'] := sEmpNo_;
O.S['TOCSG_LA_CODE'] := sCode;
O.S['TOCSG_LA_DATA'] := sMsg;
if IsUseHostNameOnly then
O.S['TOCSG_LA_HOSTNAME'] := sComName_
else
O.S['TOCSG_LA_HOSTNAME'] := sUserName_;
O.S['TOCSG_LA_LASTCONNDATE'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
if NicService_ <> nil then
begin
O.S['TOCSG_LA_MACADDR'] := NicService_.GetIP;
O.S['TOCSG_LA_REMOTEIP'] := NicService_.GetMAC;
end else begin
O.S['TOCSG_LA_MACADDR'] := 'ip';
O.S['TOCSG_LA_REMOTEIP'] := 'mac';
end;
end;
Guard(ss, TStringStream.Create(O.AsJSon, TEncoding.UTF8));
if bIsNewApi_ then
begin
HTTP.Request.CustomHeaders.Values['requestType'] := sReq;
sResult := HTTP.Post(sDestIPort_ + 'eventIncident.do', ss);
end else begin
HTTP.Request.CustomHeaders.Values['requestType'] := '123119';
sResult := HTTP.Post(sDestSvrUrl_, ss);
end;
if (sResult = '') and (HTTP.ResponseCode = 200) then
Result := true;
except
{$IFDEF TRACE1}
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DirectSendEventLog()');
{$ENDIF}
end;
end;
procedure TManagerService.SendScreenRecord(sReason, sMp4Path: String; nMilSec: Integer);
var
LogInfo: TLogInfo;
O, OA: ISuperObject;
sFid, sUpUrl: String;
begin
try
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := MONITOR_appScreenRec;
LogInfo.sLogId := StrsReplace(TGUID.NewGuid.ToString, ['{', '}'], '');
var sData: String := GetPostData(Format('aapi/files/issue?origin=inc.%s&type=appScreenRec', [LogInfo.sLogId]), '');
if sData = '' then
begin
_Trace('SendScreenRecord() .. Fail .. Upload URL 가져오기 실패');
exit;
end;
O := SO(sData);
sFid := O.S['fileId'];
sUpUrl := O.S['uploadUrl'];
SendFileNor(false, 'file', sUpUrl, sMp4Path, 0, 200, crtDelete);
OA := TSuperObject.Create(stArray);
OA.AsArray.Add(sFid);
LogInfo.sThumbIds := OA.AsJSon;
LogInfo.sAppName := sReason;
LogInfo.sSummary := Format('App Screen Record (MilSec=%d)', [nMilSec]);
SendEventLogEx(@LogInfo);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendScreenRecord()');
end;
end;
procedure TManagerService.SendIntegrityAuditLog(const JsonReport: string);
var
KeyPath, ExpectedHash, ActualHash, Reason: string;
Root, FileObj, SuccessArray, FailArray: ISuperObject;
JsonLog, sHostName, sEmpId: string;
IsSuccess: Boolean;
begin
try
Root := SO(JsonReport);
if Root = nil then
begin
Exit;
end;
sEmpId := gMgSvc.AgentModel.EmpNo;
if IsUseHostNameOnly then
sHostName := gMgSvc.ComName
else
sHostName := gMgSvc.UserName;
Root.S['type'] := 'integrity';
Root.S['hostname'] := sHostName;
Root.S['empId'] := sEmpId;
Root.S['loggedAt'] := FormatDateTime('yyyy-mm-dd"T"hh:nn:ss"+09:00"', Now);
Root.S['startedAt'] := agentStatTime_;
ThdEvent_.Push(Root.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendIntegrityAuditLog()');
end;
end;
procedure TManagerService.SendStartAgentAuditLog;
var
sHostName, sEmpId: string;
O: ISuperObject;
begin
try
O := SO;
{
"startedAt": "2026-02-27T21:33:46Z",
"type": "startedAgent",
"empId": "test1234",
"hostname": "DESKTOP-R14E1EI\tocsg",
"loggedAt": "2026-02-27T21:35:46Z"
}
sEmpId := gMgSvc.AgentModel.EmpNo;
if IsUseHostNameOnly then
sHostName := gMgSvc.ComName
else
sHostName := gMgSvc.UserName;
O.S['type'] := 'startedAgent';
O.S['hostname'] := sHostName;
O.S['empId'] := sEmpId;
O.S['loggedAt'] := FormatDateTime('yyyy-mm-dd"T"hh:nn:ss"+09:00"', Now);
O.S['startedAt'] := agentStatTime_;
_Trace('[MGKIM] SendStartAgentAuditLog.. %s',[O.AsString], 1);
ThdEvent_.Push(O.AsString);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendStartAgentAuditLog()');
end;
end;
procedure TManagerService.PopupMessage(nType: Integer; sData: String = '');
var
O: ISuperObject;
bVulMsg,
bApproval: Boolean;
sTemp: String;
begin
if hRcvHwnd_ = 0 then
exit;
if (CUSTOMER_TYPE = CUSTOMER_SERVE1) and
(nType = TYPE_MSG_PREVENT_FILEWRITE) then
begin
// 파일 생성 차단 알림은 1분에 한번만 뜨게 해야함 24_0718 10:58:54 kku
if SecondsBetween(dtSV1FileBlockNoti_, Now) < 60 then
exit;
dtSV1FileBlockNoti_ := Now;
end;
// 화면 잠금 상태에서는 팝업 되지 않도록 보완 22_1118 08:03:28 kku
// 현재 화면 잠금 상태에서 팝업되면 에디트 박스에 포커스가 가기전까지 텍스트가 표시 되지 않는 문제 있음
if FindWindow('TDlgLockScreen', nil) <> 0 then
exit;
bApproval := false;
case nType of
TYPE_MSG_CTTSCH_START :
begin
// if (pProcCampn_ <> nil) and pProcCampn_.Info.bScanNotice then
begin
O := SO;
O.I['T'] := nType;
if sData <> '' then
O.S['D'] := sData;
SendMessage(hRcvHwnd_, WM_POPUP_MSG2, 0, NativeInt(O.AsString));
end;
exit;
end;
TYPE_MSG_CTTSCH_COMPLETE :
begin
if (pProcCampn_ <> nil) and (pProcCampn_.Info.nNotiIfCnt > 0) then
begin
var StrList: TStringList;
Guard(StrList, TStringList.Create);
SplitString(sData, '|', StrList);
if (StrList.Count > 1) and (StrToIntDef(StrList[1], 0) >= pProcCampn_.Info.nNotiIfCnt) then
begin
O := SO;
O.I['T'] := nType;
if sData <> '' then
O.S['D'] := sData;
SendMessage(hRcvHwnd_, WM_POPUP_MSG_PI, 0, NativeInt(O.AsString));
end;
end
{$IFDEF DEBUG}
else begin // for Test
O := SO;
O.I['T'] := nType;
if sData <> '' then
O.S['D'] := sData;
SendMessage(hRcvHwnd_, WM_POPUP_MSG_PI, 0, NativeInt(O.AsString));
end
{$ENDIF};
exit;
end;
TYPE_MSG_CAMPN_FILEENC :
begin
if pProcCampn_ <> nil then
begin
O := SO;
O.I['T'] := nType;
SendMessage(hRcvHwnd_, WM_POPUP_MSG_PI, 0, NativeInt(O.AsString));
end;
exit;
end;
end;
case nType of
TYPE_MSG_NOTIFICATION :
begin
if not PrefModel.IsNoticeEnable then
exit;
end;
TYPE_REQ_APPROVAL,
TYPE_RES_APPROVAL : bApproval := true;
else begin
{$IFNDEF DEBUG} // TEST_KJ
if ModePolicy.NotifyKind = nfkNone then
// if (ModePolicy.NotifyKind = nfkNone) and (nType <> TYPE_MSG_UPDATE) then
exit;
{$ENDIF}
// 팝업 중복 거르기
case nType of
TYPE_MSG_PREVENT_FILECHANGE,
TYPE_MSG_PREVENT_FILEWRITE :
begin
sTemp := StringReplace(sData, ':', '_', [rfReplaceAll]);
sTemp := StringReplace(sTemp, '\', '_', [rfReplaceAll]);
sTemp := 'Global\PV_' + sTemp;
if MutexExists(sTemp) then
exit;
end;
end;
bVulMsg := false;
case nType of
TYPE_MSG_SAFEAPPLIED,
TYPE_MSG_OLD_WINDOWS,
TYPE_MSG_VUL_OS,
TYPE_MSG_VUL_PW,
TYPE_MSG_VUL_AV,
TYPE_MSG_VUL_FW,
TYPE_MSG_VUL_SCREEN,
TYPE_MSG_VUL_ALLOWACCESS,
TYPE_MSG_VUL_EMPNO : bVulMsg := true;
// TYPE_MSG_NOTIFICATION,
TYPE_MSG_UPDATE,
TYPE_MSG_AFTERREPORT :
begin
// 항상 표시되기 위해 조치한다. 22_0819 13:50:29 kku
case ModePolicy.NotifyKind of
nfkVul: bVulMsg := true;
nfkPol: bVulMsg := false;
end;
end;
end;
case ModePolicy.NotifyKind of
// nfkNone : if nType <> TYPE_MSG_UPDATE then exit;
nfkNone : exit;
nfkVul: if not bVulMsg then exit;
nfkPol: if bVulMsg then exit;
end;
end;
end;
if (nType = TYPE_MSG_PREVENT_CAPAPP) and IsHD then
begin
// 별도 팝업 처리
O := SO;
O.I['T'] := nType;
if sData <> '' then
O.S['D'] := sData;
SendMessage(hRcvHwnd_, WM_POPUP_MSG2, 0, NativeInt(O.AsString));
exit;
end;
// todo : 알림 세부 정책 추가 시 삭제해야함 23_0403 13:59:37 kku
if (nType = TYPE_MSG_PREVENT_FILECHANGE) and ModePolicy.FileMonOnlyLog then
exit;
O := SO;
O.I['T'] := nType;
O.B['A'] := bApproval;
if sData <> '' then
O.S['D'] := sData;
SendMessage(hRcvHwnd_, WM_POPUP_MSG, 0, NativeInt(O.AsString));
end;
procedure TManagerService.PopupSystemMsg(nType: Integer);
begin
if IsNewApi then
exit;
if CUSTOMER_TYPE = CUSTOMER_SANKYO then
begin
// 다이이찌산쿄의 경우 "알림팝업 여부" 정책 OFF 시 모든 알림 차단 22_0615 08:49:19 kku
if ModePolicy.NotifyKind = nfkNone then
exit;
end;
if hRcvHwnd_ <> 0 then
SendMessage(hRcvHwnd_, WM_POPUP_MSG_SYSTEM, nType, 0);
end;
procedure TManagerService.PopupLicensed;
var
HTTP: TIdHTTP;
SSL: TIdSSLIOHandlerSocketOpenSSL;
sTemp: String;
begin
try
if hRcvHwnd_ = 0 then
exit;
if PrefModel.NoticeContent <> '' then
begin
// 공지사항
sNoticeContent_ := PrefModel.NoticeContent;
PopupMessage(TYPE_MSG_NOTIFICATION, sNoticeContent_);
end;
if PrefModel.IsDailyEulaCheck then
begin
if IsToday(AgentModel.EulaDT) then
exit;
end else begin
if (AgentModel_.EulaDT <> 0) then
exit;
end;
if not PrefModel.IsEulaSubmit then
exit;
if MutexExists(MUTEX_LICENSE) then
exit;
sTemp := '';
// 보안서약서 보여주기전에 내용 업데이트 해줌 22_1129 09:59:17 kku
try
if bIsNewApi_ then
begin
// 신규서버에서는 팝업 시 값을 채워주게 했지만
// 2.6 방식으로 맞춘다 23_0830 13:06:16 kku
sTemp := PrefModel_.EulaBody;
end else
// 전역 포트 블럭으로 사용동의서 가져오기 전에 짤릴 수 있어서 미리 받아놓는다 22_0503 10:02:52 kku
if sAgentId_ <> '' then
begin
var sDest: String := StringReplace(sDestSvrUrl_, 'agentLogRequest.do', 'agentEulaContent', [rfReplaceAll]);
sDest := StringReplace(sDest, 'agentLogRequests.do', 'agentEulaContent', [rfReplaceAll]);
sDest := sDest + '/' + sAgentId_;
Guard(SSL, TIdSSLIOHandlerSocketOpenSSL.Create(nil));
SSL.SSLOptions.Method := sslvSSLv23;
SSL.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_1, sslvTLSv1];
Guard(HTTP, TIdHTTP.Create(nil));
HTTP.IOHandler := SSL;
with HTTP do
begin
HandleRedirects := true;
Request.Clear;
Request.UserAgent := 'Mozilla/5.0';
Request.ContentType := 'application/xml';
Request.AcceptCharSet := 'UTF-8';
// Request.Connection := 'Keep-Alive';
// Request.CustomHeaders.Values['Keep-Alive'] := 'timeout=300, max=100';
Request.Connection := 'close';
HTTPOptions := HTTPOptions - [hoKeepOrigProtocol];
HTTPOptions := HTTP.HTTPOptions + [hoForceEncodeParams];
ConnectTimeout := 3000;
ReadTimeout := 3000;
end;
sTemp := HTTP.Get(sDest);
// 보안서약서 비어 있는지 체크 22_0727 16:19:51 kku
if (sTemp <> '') and sTemp.EndsWith('null}') then
sEulaContent_ := '';
end;
if (sTemp <> '') and (sEulaContent_ <> sTemp) then
begin
sEulaContent_ := sTemp;
if AgentModel_.EulaTxt <> sEulaContent_ then
begin
AgentModel_.EulaTxt := sEulaContent_;
AgentModel_.Save;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. PopupLicensed() .. GetEulaContent ..');
end;
if sEulaContent_ <> '' then
sTemp := sEulaContent_
else
sTemp := AgentModel_.EulaTxt;
SendMessage(hRcvHwnd_, WM_POPUP_LICENSE, 0, NativeInt(sTemp));
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. PopupLicensed()');
end;
end;
procedure TManagerService.PopupAfterReport;
begin
try
if hRcvHwnd_ = 0 then
exit;
// if not IsUseAfterReport then
// exit;
if MutexExists(MUTEX_AFTERREPORT) then
exit;
if AgentModel_.AfterRptDT = 0 then
begin
AgentModel_.AfterRptDT := Now;
AgentModel_.Save;
end;
SendMessage(hRcvHwnd_, WM_POPUP_AFTERREPORT, 0, 0);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. PopupAfterReport()');
end;
end;
procedure TManagerService.RefreshView;
begin
if (hRcvHwnd_ <> 0) then
SendMessage(hRcvHwnd_, WM_REFRESH_VIEW, 0, 0);
end;
procedure TManagerService.UpdateScreenLogo(bForce: Boolean = false);
begin
if (hRcvHwnd_ <> 0) then
SendMessage(hRcvHwnd_, WM_UPDATE_SCREENLOGO, BooleanToInt(bForce, 1, 0), 0);
end;
procedure TManagerService.DoCheckOsUpdate;
begin
if ThdOsUpdateScan_ <> nil then
ThdOsUpdateScan_.DoCheckUpdate;
end;
procedure TManagerService.ProcessVpnConnect;
var
sPath: String;
begin
if IsUseCaller then
begin
sPath := GetRunExePathDir + DIR_CONF + EXE_IC;
if FileExists(sPath) then
ExecutePath_hide(sPath);
end;
if hRcvHwnd_ <> 0 then
PostMessage(hRcvHwnd_, WM_REFRESH_CLIPBOARDCHAIN, 0, 0);
bDoEmpNoCheck_ := IsCheckEmpNo and PrefModel.IsEmpVerify;
if ModePolicy.UsbBlockKind = ubkBlock then
DoEjectUsbDrives;
PopupLicensed;
end;
procedure TManagerService.ProcessVpnDisconnect;
begin
ActiveConnectList.Clear;
bIsTemporaryConn_ := false;
bIsServiceAvailable_ := false;
if IsUseCaller then
TerminateProcessByName(EXE_IC);
end;
function TManagerService.IsOfflineMode: Boolean;
var
sIp, sMac: String;
nOffIfSec: Integer;
begin
Result := false;
try
// 매니저 연결 해제 후 5분 후에 Offline 모드로 변경 24_0619 09:38:57 kku
if bIsNewApi_ then
begin
// 2.7의 경우 항상 Result가 false로 처리됨.
if IsCJ_Affiliates then
begin
// CJ는 사번 미인증 상태가 오프라인 모드 24_1218 13:53:43 kku
bIsOffline_ := (sEmpNo_ = CJ_EMPTY_EMPNO); // or not bIsEmpNoOk_;
end else
if not bIsConnected_ and not bIsOffline_ then
begin
if dtApDisconn_ = 0 then
dtApDisconn_ := Now;
case CUSTOMER_TYPE of
CUSTOMER_KDNVN : nOffIfSec := 60;
else nOffIfSec := 300;
end;
var dwOverSec: DWORD := dwStatusInterval_;
if dwOverSec = 0 then
dwOverSec := PrefModel_.HealthCheckMilSec;
if dwOverSec > 1000 then
dwOverSec := ((dwOverSec div 1000) * 2) + nOffIfSec
else
dwOverSec := nOffIfSec;
// 5분동안 서버 미접이면 오프라인 24_0422 09:50:46 kku
// 기존 nOffIfSec에서 (통신주기 * 2) + nOffIfSec으로 변경 24_0919 14:49:55 kku
if SecondsBetween(Now, dtApDisconn_) > dwOverSec then
bIsOffline_ := true;
end;
end else begin
sIp := NicService.GetIP;
sMac := NicService.GetMAC;
if bIsOffline_ then
begin
if gMgSvc.NicService.IsActiveAP then
begin
bIsOffline_ := false;
dtApDisconn_ := 0;
end else
Result := true;
end else
if not gMgSvc.NicService.IsActiveAP or
(sIp = '') or (sIp = IP_NULL) or
(sMac = '') or (sMac = MAC_NULL) then
begin
gMgSvc.SetConnected(false, false);
if not bIsOffline_ and PrefOffline_.Loaded then
begin
if dtApDisconn_ = 0 then
dtApDisconn_ := Now;
if SecondsBetween(Now, dtApDisconn_) > 60 then
bIsOffline_ := true;
end;
Result := true;
end;
end;
// case CUSTOMER_TYPE of
// CUSTOMER_INZENT :
// begin
// if not bIsConnected_ and not bIsOffline_ then
// begin
// if dtApDisconn_ = 0 then
// dtApDisconn_ := Now;
//
// // 5분동안 서버 미접이면 오프라인 24_0422 09:50:46 kku
// if SecondsBetween(Now, dtApDisconn_) > 300 then
// bIsOffline_ := true;
// end;
// end;
// else begin
// sIp := NicService.GetIP;
// sMac := NicService.GetMAC;
// if bIsOffline_ then
// begin
// if gMgSvc.NicService.IsActiveAP then
// begin
// bIsOffline_ := false;
// dtApDisconn_ := 0;
// end else
// Result := true;
// end else
// if not gMgSvc.NicService.IsActiveAP or
// (sIp = '') or (sIp = IP_NULL) or
// (sMac = '') or (sMac = MAC_NULL) then
// begin
// gMgSvc.SetConnected(false, false);
// if not bIsOffline_ and PrefOffline_.Loaded then
// begin
// if dtApDisconn_ = 0 then
// dtApDisconn_ := Now;
//
// if SecondsBetween(Now, dtApDisconn_) > 60 then
// bIsOffline_ := true;
// end;
//
// Result := true;
// end;
// end;
// end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsOfflineMode()');
end;
end;
function TManagerService.IsSearchingPersonalInfo: Boolean;
begin
try
Result := not bTerminateThdScanSch_ and (ThdScanSch_ <> nil);
if Result then
case ThdScanSch_.WorkState of
tsInit,
tsWorking: ;
else
begin
llCampnEncCnt_ := ThdScanSch_.TotalEncCount;
llCampnEncFailCnt_ := ThdScanSch_.TotalEncFailCount;
if DlgEncCampn_ <> nil then
begin
DlgEncCampn_.Show;
DlgEncCampn_ := nil;
end;
Result := false;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsSearchingPersonalInfo()');
end;
end;
procedure TManagerService.StartPiSchTask(aOpt: TFileScanOpt; dtScan: TDateTime; bSendEvent: Boolean = true);
var
DrvList: TStringList;
i: Integer;
DrvEx: TTgDriveExtent;
sInfoDir: String;
begin
try
if ThdScanSch_ <> nil then
FreeAndNil(ThdScanSch_);
aOpt.CttSchOpt.sMK := GetMK(false);
if dtScan = 0 then
dtScan := MgCttSch_.GetTastRecentDT(aOpt.sScanId);
if aOpt.CttSchOpt.bIncZip then
aOpt.sScanExt := aOpt.sScanExt + '|' + COMPRESS_EXTS; // '|zip';
if aOpt.sTgDirs = '' then
begin
aOpt.sTgDirs := GetDrivesFromMask(GetLogicalDrives, false, true);
if aOpt.sTgDirs = '' then
begin
_Trace('Fail .. StartPiSchTask(), Not found drive');
exit;
end;
Guard(DrvEx, TTgDriveExtent.Create);
Guard(DrvList, TStringList.Create);
SplitString(aOpt.sTgDirs, ',', DrvList);
aOpt.sTgDirs := '';
for i := 0 to DrvList.Count - 1 do
begin
if GetDriveExtent(DrvList[i]).liExtentLength.QuadPart <> 0 then
SumString(aOpt.sTgDirs, DrvList[i], '|');
end;
if aOpt.sTgDirs = '' then
begin
_Trace('Fail .. StartPiSchTask(), Not found drive 2');
exit;
end;
end;
sInfoDir := GetRunExePathDir + DIR_CTTSCHRST;
if not ForceDirectories(sInfoDir) then
_Trace('Fail .. Create sch workdir ..');
sSchRstPath_ := sInfoDir + Format('%s.%s', [aOpt.sScanId, DAT_CTTSCHRSTDATA]);
sSchRstExpPath_ := sInfoDir + Format('%s.%s', [aOpt.sScanId, DAT_CTTSCHRSTDATA_EXP]);
DeleteFile(PChar(sSchRstPath_));
DeleteFile(PChar(sSchRstExpPath_));
if not FileExists(sInfoDir + Format('%s.%s', [aOpt.sScanId, DAT_CTTSCHOPT])) then
begin
// DeleteFile(PChar(Format('%s%s.%s', [sInfoDir, aOpt.sScanId, DAT_CTTSCHRST])));
// DeleteFile(PChar(Format('%s%s.%s', [sInfoDir, aOpt.sScanId, DAT_CTTSCHRSTDATA])));
// DeleteFile(PChar(Format('%s%s.%s', [sInfoDir, aOpt.sScanId, DAT_CTTSCHOPT])));
SaveJsonObjToEncFile(TTgJson.ValueToJsonObject<TFileScanOpt>(aOpt),
sInfoDir + Format('%s.%s', [aOpt.sScanId, DAT_CTTSCHOPT]), PASS_STRENC);
end;
ThdScanSch_ := TThdSchFileScan.Create(aOpt.sTgDirs, aOpt, dtScan, bSendEvent);
ThdScanSch_.OnScanSearchBegin := OnPiSchTaskBegin;
ThdScanSch_.OnScanSearchEnd := OnPiSchTaskEnd;
ThdScanSch_.StartThread;
RefreshView;
PopupMessage(TYPE_MSG_CTTSCH_START);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. StartPiSchTask()');
end;
end;
procedure TManagerService.StopPiSchTask;
begin
try
if ThdScanSch_ <> nil then
begin
// 다시 검색 되지 않도록 해줌 22_0817 13:21:48 kku
if (ThdScanSch_.WorkState = tsWorking) and (ThdScanSch_.CttSchProg.sScanId <> '') then
MgCttSch_.CompleteTask(ThdScanSch_.CttSchProg.sScanId, ThdScanSch_.ScanDate);
FreeAndNil(ThdScanSch_);
RefreshView;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. StopPiSchTask()');
end;
end;
procedure TManagerService.OnPiSchTaskBegin(aSender: TObject);
begin
if MgFnd_ <> nil then
FreeAndNil(MgFnd_);
{$IFDEF DEBUG} DeleteFile(PChar(GetRunExePathDir + JSON_PI_TEST)); {$ENDIF}
MgFnd_ := TManagerFound.Create;
end;
procedure TManagerService.OnPiSchTaskEnd(aSender: TObject);
var
dtEnd: TDateTime;
O, OA: ISuperObject;
sCurDir,
sScanId,
sPath,
sTime,
sResult: String;
bClearData: Boolean;
ScanBlockKind: TScanBlockKind;
nPersonalInfoFileMax: Integer;
begin
try
if ThdScanSch_ = nil then
exit;
sScanId := ThdScanSch_.CttSchProg.sScanId;
dtEnd := Now;
sTime := ConvSecBetweenToProgTime(ThdScanSch_.BeginDT, dtEnd);
O := SO;
O.S['ID'] := sScanId;
O.S['TID'] := ThdScanSch_.CttSchProg.sTaskId;
O.S['BeginDT'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', ThdScanSch_.BeginDT);
O.S['EndDT'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtEnd);
O.I['WorkSec'] := SecondsBetween(ThdScanSch_.BeginDT, dtEnd);
O.S['WorkTime'] := sTime;
O.I['TotalFileCount'] := ThdScanSch_.TotalFileCount;
O.I['TargetFileCount'] := ThdScanSch_.TotalTgFileCount;
O.I['FoundFileCount'] := ThdScanSch_.FoundFileCount;
O.S['FoundSInfo'] := MgFnd_.ToEntInfoStr;
O.O['FoundInfo'] := MgFnd_.ToJsonObj;
sCurDir := GetRunExePathDir;
{$IFDEF DEBUG} SaveJsonObjToFile(O, sCurDir + JSON_PI_TEST); {$ENDIF}
sResult := MgFnd_.ToEntInfoStr;
if ForceDirectories(sCurDir + DIR_CTTSCHRST) then
begin
if sScanId <> '' then
SaveJsonObjToFile(O, Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHRST]))
else
SaveJsonObjToFile(O, sCurDir + DIR_CTTSCHRST + DAT_CTTSCHRST);
PopupMessage(TYPE_MSG_CTTSCH_COMPLETE, sTime + '|' + IntToStr(ThdScanSch_.FoundFileCount));
end;
bClearData := true;
ScanBlockKind := PrefModel_.ScanBlockKind;
nPersonalInfoFileMax := PrefModel_.PersonalInfoFileMax;
if sScanId <> '' then
begin
ThdScanSch_.UpdateProgress('complete', true, sResult);
MgCttSch_.CompleteTask(sScanId, ThdScanSch_.ScanDate);
if (nPersonalInfoFileMax > 0) and
(nPersonalInfoFileMax <= ThdScanSch_.FoundFileCount) then
begin
SetSchRstVul(true);
bClearData := false;
SendEventLog(URI_USER_ACTION, STATUS_FILESCAN,
Format('Found=%d, File=%d', [ThdScanSch_.FoundCount, ThdScanSch_.FoundFileCount]));
PopupMessage(TYPE_MSG_CTTSCH_VULMODE);
end;
end;
if nPersonalInfoFileMax = 0 then
begin
DeleteDir(sCurDir + DIR_CTTSCHRST);
end else
if bClearData then
begin
DeleteFile(PChar(Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHRST])));
DeleteFile(PChar(Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHRSTDATA])));
DeleteFile(PChar(Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHOPT])));
end;
if bSchRstVul_ and (GetPersonalInfoResults = 0) then
SetSchRstVul(false);
{$IFDEF DEBUG}
sPath := GetRunExePathDir + 'PersonalInfo.txt';
if FileExists(sPath) then
DeleteFile(PChar(sPath));
WriteLnFileEndUTF8(sPath, sResult);
{$ENDIF}
if sScanId <> '' then
_Trace('ProcessCttSchSchedule() End .. ScanId=%s', [sScanId]);
if MgFnd_ <> nil then
FreeAndNil(MgFnd_);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnPiSchTaskEnd()');
end;
llCampnEncCnt_ := ThdScanSch_.TotalEncCount;
llCampnEncFailCnt_ := ThdScanSch_.TotalEncFailCount;
bTerminateThdScanSch_ := true;
RefreshView;
end;
procedure TManagerService.ProcessPiSchFound(pResult: PSchResult);
var
StrList,
RstList: TStringList;
i: Integer;
begin
try
Guard(StrList, TStringList.Create);
SplitString(pResult.sSchName, RESULT_SEPARATOR, StrList);
Guard(RstList, TStringList.Create);
SplitString(pResult.sResultStr, RESULT_SEPARATOR, RstList);
{$IFDEF DEBUG}
ASSERT(StrList.Count = RstList.Count);
{$ELSE}
if StrList.Count <> RstList.Count then
begin
_Trace('Fail .. ProcessPersonalInfoFound() .. SchName <> RstCount');
exit;
end;
{$ENDIF}
pResult.sSchName := ''; // 보정해준다.
for i := 0 to StrList.Count - 1 do
begin
if (i = 0) and (StrList[i] = '*KWD*') then
begin
MgFnd_.PushFoundKeyword(RstList[i]);
end else begin
MgFnd_.PushFoundPattern(StrList[i], GetCountOverlapWordsCount(RstList[i]));
SumString(pResult.sSchName, ExtractFileName(StrList[i]), ';');
end;
end;
if ThdScanSch_ <> nil then
begin
var nProcType: Integer := 0;
if IsForcePI and not pResult.bDrm and
(PrefModel_.ScanBlockKind = sbkDrmEnc) and FileExists(pResult.sPath) then
begin
try
var sTaskDir: String := 'C:\ProgramData\HE\EncTask\';
if ForceDirectories(sTaskDir) then
begin
if not TTgEncrypt.CheckSign(pResult.sPath, SIG_DRM) then
begin
var sTgEncPath: String := GetSameFileNameInc(sTaskDir + '$Tmp' + ExtractFileName(pResult.sPath));
if CopyFile(PChar(pResult.sPath), PChar(sTgEncPath), false) then
begin
DeleteFile(PChar(pResult.sPath));
SaveStrToFile(sTgEncPath + '.i', pResult.sPath, TEncoding.UTF8);
var enc: TTgDrmEnc;
var sDept: String := sDeptName_;
if sDept = '' then
sDept := PrefModel_.DeptName;
var bResult: Boolean := false;
enc := TTgDrmEnc.Create(pResult.sPath);
try
enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, sEmpNo_, sUserName_,
sDept, PrefModel_.PolicyName, CUSTOMER_TYPE);
bResult := enc.EncryptFromFile(GetMK, sTgEncPath);
finally
FreeAndNil(enc);
end;
if bResult then
begin
DeleteFile(PChar(sTgEncPath));
DeleteFile(PChar(sTgEncPath + '.i'));
nProcType := 1;
SendEventLog(URI_USER_ACTION, PREVENT_DRM_ENCRYPT, pResult.sPath);
end else begin
// MoveFile_wait(sTgEncPath, pResult.sPath, 3);
if CopyFile(PChar(sTgEncPath), PChar(pResult.sPath), false) then
DeleteFile(PChar(sTgEncPath));
DeleteFile(PChar(sTgEncPath + '.i'));
TTgTrace.T('Fail .. MgSvc.ProcessPiSchFound.EncFile(), Path=%s', [pResult.sPath]);
end;
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessPersonalInfoFound() .. enc');
end;
end else
if IsForcePI and not pResult.bDrm and
(PrefModel_.ScanBlockKind = sbkDelete) and FileExists(pResult.sPath) then
begin
if PerfectDeleteFile(pResult.sPath, 3) then
nProcType := 2;
end else
if (ThdScanSch_.CttSchProg.sScanId <> '') and MgCttSchExp_.HasFileHash(pResult.sPath) then // 파일 해시로 예외 체크 추가 23_0414 09:58:24 kku
nProcType := 3;
if (nProcType = 0) and not pResult.bDrm then
begin
// DRM 파일은 취약 카운트에 포함하지 않음 22_1123 15:27:15 kku
ThdScanSch_.IncFoundCount(pResult.nHitCnt);
ThdScanSch_.IncFoundFileCount;
end;
if ThdScanSch_.CttSchProg.sScanId <> '' then
begin
if ThdScanSch_.IsSendEvent then
SendCttSchDetailInfo(ThdScanSch_.CttSchProg.sTaskId, pResult, nProcType);
if sSchRstPath_ <> '' then
with pResult^ do
WriteLnFileEndUTF8(sSchRstPath_,
Format('%s<!>%d<!>%s<!>%s<!>%s', [sSchName, nHitCnt, sPath, RstList.CommaText, sFName]));
if (nProcType = 3) and (sSchRstExpPath_ <> '') then
with pResult^ do
WriteLnFileEndUTF8(sSchRstExpPath_, pResult.sPath);
end else begin
with pResult^ do
WriteLnFileEndUTF8(GetRunExePathDir + DIR_CTTSCHRST + DAT_CTTSCHRSTDATA,
Format('%s<!>%d<!>%s<!>%s<!>%s', [sSchName, nHitCnt, sPath, RstList.CommaText, sFName]));
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessPersonalInfoFound()');
end;
end;
procedure TManagerService.ProcessCampnFound(pResult: PSchResult);
var
i: Integer;
StrList,
RNameList,
RstList: TStringList;
bCollectFile: Boolean;
Respaction: TCampnRespaction;
sTemp: String;
begin
try
if ThdScanSch_ = nil then
exit;
if pProcCampn_ = nil then
exit;
Guard(StrList, TStringList.Create);
SplitString(pResult.sSchName, RESULT_SEPARATOR, StrList);
Guard(RstList, TStringList.Create);
SplitString(pResult.sResultStr, RESULT_SEPARATOR, RstList);
Guard(RNameList, TStringList.Create);
for i := 0 to StrList.Count - 1 do
begin
if (i = 0) and (StrList[i] = '*KWD*') then
begin
MgFnd_.PushFoundKeyword(RstList[i]);
end else begin
sTemp := MgRule_.GetRuleNameFromId(StrList[i]);
RNameList.Add(sTemp);
MgFnd_.PushFoundPattern(sTemp, GetCountOverlapWordsCount(RstList[i]));
// SumString(pResult.sSchName, ExtractFileName(StrList[i]), ';');
end;
end;
if pResult.nHitCnt > 0 then
begin
bCollectFile := pProcCampn_.Info.bGetFile; // and not pResult.bDrm;
Respaction := pProcCampn_.Info.Respaction;
ThdScanSch_.IncFoundCount(pResult.nHitCnt);
ThdScanSch_.IncFoundFileCount;
// if not pResult.bDrm then
// _Trace('CampnFound .. Path=%s', [pResult.sPath], 9);
end else begin
bCollectFile := false;
if pProcCampn_.Info.CampnType = ctForceEnc then
begin
if IsUseEncOnlyAIP or bFirstAip_ then
Respaction := crtAIP
else if not NotUseDRM then
Respaction := crtDRM;
end;
end;
case Respaction of
crtDRM,
crtAIP:
begin
if pResult.bMakeDrm or pResult.bDrm then
ThdScanSch_.IncEncFileCount
else
ThdScanSch_.IncEncFailFileCount;
end;
crtDelete,
crtPerDel : ThdScanSch_.IncDelFileCount;
else
begin
if pResult.bDrm then
ThdScanSch_.IncEncFileCount;
end;
end;
if pResult.sResultStr = '*NoMatch*' then // 증분 재검사 시 검출된거 없는거 구분... 24_0620 18:19:09 kku
begin
// 증분검사, 기본결과유지 - 재검사 시 검출 안된 경우 목록에서 빼주기 24_0611 10:10:04 kku
NoMatchList_.Add(pResult.sPath);
exit;
end else
begin
var unableFile: Boolean;
unableFile:= False;
if Pos('unable to analysis', pResult.sResultStr) > 0 then
begin
bCollectFile:= True;
unableFile:= True;
_Trace('[MGKIM] unable to analysis ok');
end;
MgCampn_.SendCampaignResultFile(ThdScanSch_.CttSchProg.sTaskId,
pResult, ThdScanSch_.FoundFileCount, bCollectFile, pProcCampn_.Info.CttSchLimitMB, Respaction); // llProc 이거 값 업데이트 확인
// if pResult.bMakeDrm and (pResult.nHitCnt = 0) then
if (pResult.nHitCnt = 0) and not unableFile then // 일반파일 암호화 실패시 목록에 포함되지 않도록 수정 24_0112 08:48:44 kku
exit;
end;
if not bCollectFile then
begin
case Respaction of
// 암호화 이미 처리됨
crtDelete,
crtPerDel: ThdReact_.AddEnt(Respaction, pResult.sPath);
end;
end;
case pProcCampn_.Info.CampnType of
ctScan,
ctScanPatial :
begin
if ThdScanSch_.CttSchProg.sScanId <> '' then
begin
if pProcCampn_.sSchRstPath <> '' then
begin
with pResult^ do
begin
WriteLnFileEndUTF8(pProcCampn_.sSchRstPath,
Format('%s<!>%d<!>%s<!>%s<!>%s<!>%s<!>%s',
[RNameList.CommaText, nHitCnt, sPath, RstList.CommaText, sFName,
pResult.sSchName, pResult.sResultStr])); // 증분검사 결과에서 결과 정보 합치기를 위해 추가 24_0423 13:54:42 kku
end;
end;
// if (nProcType = 3) and (sSchRstExpPath_ <> '') then
// with pResult^ do
// WriteLnFileEndUTF8(sSchRstExpPath_, pResult.sPath);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessCampnFound()');
end;
end;
procedure TManagerService.UpdateCttSchVulState(bForce: Boolean = false);
begin
if not IsUsePiVul then
exit;
if bForce or bSchRstVul_ then
begin
// 개인정보검출결과 초과 취약 체크 24_0311 15:20:05 kku
SetSchRstVul(MgCampn_.GetNoActionVulCampaign <> nil);
end;
end;
function TManagerService.ProcessMergeCampaignBkData(OInfo: ISuperObject): Integer;
var
sInfoDir,
sSchRstPath,
sInfoPath,
sInfoPathBk,
sSchRstPathBk: String;
StrList, DataList,
SchList, RstList: TStringList;
i, c: Integer;
sPath, sFrName, sLine: String;
MgCampExpt: TManagerCampExcept;
MgFnd: TManagerFound;
DcData: TDictionary<String,String>;
ONew, OOld: ISuperObject;
enum: TEnumerator<String>;
bCatLine: Boolean;
begin
Result := 0;
try
if ThdScanSch_ <> nil then
Result := ThdScanSch_.FoundFileCount;
if pProcCampn_ = nil then
exit;
sSchRstPathBk := GetRunExePathDir + DIR_CTTSCHRST_BACKUP + Format('%s.%s', [pProcCampn_.Info.sId, DAT_CTTSCHRSTDATA]);
if not FileExists(sSchRstPathBk) then
exit;
sInfoPathBk := GetRunExePathDir + DIR_CTTSCHRST_BACKUP + Format('%s.%s', [pProcCampn_.Info.sId, DAT_CTTSCHRST]);
sInfoDir := GetRunExePathDir + DIR_CTTSCHRST;
if not ForceDirectories(sInfoDir) then
exit;
sSchRstPath := sInfoDir + Format('%s.%s', [pProcCampn_.Info.sId, DAT_CTTSCHRSTDATA]);
sInfoPath := sInfoDir + Format('%s.%s', [pProcCampn_.Info.sId, DAT_CTTSCHRST]);
if not FileExists(sSchRstPath) and (NoMatchList_.Count = 0) then
begin
CopyFile(PChar(sSchRstPathBk), PChar(sSchRstPath), false);
// MoveFile_wait(sSchRstPathBk, sSchRstPath);
if FileExists(sInfoPathBk) then
CopyFileAfOpenCheck(sInfoPathBk, sInfoPath);
// MoveFile_wait(sInfoPathBk, GetRunExePathDir + DIR_CTTSCHRST + Format('%s.%s', [pProcCampn_.Info.sId, DAT_CTTSCHRST]));
if LoadJsonObjFromFile(OOld, sInfoPath) then
begin
OOld.S['BeginDT'] := OInfo.S['BeginDT'];
OOld.S['EndDT'] := OInfo.S['EndDT'];
OOld.I['WorkSec'] := OInfo.I['WorkSec'];
OOld.S['WorkTime'] := OInfo.S['WorkTime'];
OOld.B['INC'] := true;
SaveJsonObjToFile(OOld, sInfoPath);
end;
exit;
end;
Guard(StrList, TStringList.Create);
Guard(DataList, TStringList.Create);
Guard(SchList, TStringList.Create);
Guard(RstList, TStringList.Create);
Guard(MgCampExpt, TManagerCampExcept.Create);
Guard(MgFnd, TManagerFound.Create);
Guard(DcData, TDictionary<String,String>.Create);
sLine := '';
bCatLine := false;
// 직전 데이터 추출
StrList.LoadFromFile(sSchRstPathBk, TEncoding.UTF8);
for i := 0 to StrList.Count - 1 do
begin
if StrList[i] = '' then
continue;
if bCatLine then
begin
sLine := sLine + StringReplace(StrList[i], #13#10, ' ', [rfReplaceAll]);
bCatLine := false;
end else
sLine := StringReplace(StrList[i], #13#10, ' ', [rfReplaceAll]);
SplitString(sLine, '<!>', DataList, true);
if (DataList.Count < 7) or
( (i < StrList.Count - 1) and (Pos('<!>', StrList[i + 1]) = 0) ) then
begin
bCatLine := true;
continue;
end;
sPath := UpperCase(DataList[2]);
if (not sPath.StartsWith('\\') and not FileExists(sPath)) or
MgCampExpt.IsExceptFile(sPath) then
continue;
if (NoMatchList_.Count > 0) and (NoMatchList_.IndexOf(sPath) <> -1) then
continue;
if (DataList.Count >= 5) and (DataList[4] <> '') then
sPath := sPath + ':' + DataList[4]; // 압축파일에 포함된 파일정보의 경우 존재
try
DcData.Add(sPath, sLine);
except
// 중복등 예외 넘김
continue;
end;
end;
NoMatchList_.Clear;
sLine := '';
bCatLine := false;
// 증분검사 데이터 추출
if FileExists(sSchRstPath) then
begin
StrList.LoadFromFile(sSchRstPath, TEncoding.UTF8);
for i := 0 to StrList.Count - 1 do
begin
if StrList[i] = '' then
continue;
if bCatLine then
begin
sLine := sLine + StringReplace(StrList[i], #13#10, ' ', [rfReplaceAll]);
bCatLine := false;
end else
sLine := StringReplace(StrList[i], #13#10, ' ', [rfReplaceAll]);
SplitString(sLine, '<!>', DataList, true);
if (DataList.Count < 7) or
( (i < StrList.Count - 1) and (Pos('<!>', StrList[i + 1]) = 0) ) then
begin
bCatLine := true;
continue;
end;
sPath := UpperCase(DataList[2]);
if not FileExists(sPath) or MgCampExpt.IsExceptFile(sPath) then
continue;
if (DataList.Count >= 5) and (DataList[4] <> '') then
sPath := sPath + ':' + DataList[4]; // 압축파일에 포함된 파일정보의 경우 존재
if DcData.ContainsKey(sPath) then
begin
// 이전에 있던거라면 과거 데이터를 삭제
DcData.Remove(sPath);
end;
DcData.Add(sPath, sLine);
end;
end;
Result := DcData.Count;
StrList.Clear;
if Result > 0 then
begin
Guard(enum, DcData.Values.GetEnumerator);
while enum.MoveNext do
begin
StrList.Add(enum.Current);
SplitString(enum.Current, '<!>', DataList, true);
if DataList.Count > 6 then
begin
SplitString(DataList[5], RESULT_SEPARATOR, SchList);
SplitString(DataList[6], RESULT_SEPARATOR, RstList);
for c := 0 to SchList.Count - 1 do
begin
if (c = 0) and (SchList[c] = '*KWD*') then
MgFnd.PushFoundKeyword(RstList[c])
else
MgFnd.PushFoundPattern(MgRule_.GetRuleNameFromId(SchList[c]), GetCountOverlapWordsCount(RstList[c]));
end;
end;
end;
end;
StrList.SaveToFile(sSchRstPath, TEncoding.UTF8);
if LoadJsonObjFromFile(ONew, sInfoPath) and LoadJsonObjFromFile(OOld, sInfoPathBk) then
begin
// O.I['TotalFileCount'] := ThdScanSch_.TotalFileCount;
// O.I['TargetFileCount'] := ThdScanSch_.TotalTgFileCount;
ONew.S['BeginDT'] := OInfo.S['BeginDT'];
ONew.S['EndDT'] := OInfo.S['EndDT'];
ONew.I['WorkSec'] := OInfo.I['WorkSec'];
ONew.S['WorkTime'] := OInfo.S['WorkTime'];
ONew.I['FoundFileCount'] := Result;
ONew.S['FoundSInfo'] := MgFnd.ToEntInfoStr;
ONew.O['FoundInfo'] := MgFnd.ToJsonObj;
ONew.B['INC'] := true;
SaveJsonObjToFile(ONew, sInfoPath);
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessMergeCampaignBkData()');
end;
end;
procedure TManagerService.AddFileExpEnt(sPath, sHash: String);
var
i: Integer;
pEnt: PFileExpEnt;
begin
try
Lock;
try
for i := 0 to FileExpEntList_.Count - 1 do
begin
pEnt := FileExpEntList_[i];
if CompareText(sPath, pEnt.sPath) = 0 then
begin
pEnt.sHash := sHash;
pEnt.dtReg := Now;
exit;
end;
end;
New(pEnt);
pEnt.sPath := sPath;
pEnt.sHash := sHash;
pEnt.dtReg := Now;
FileExpEntList_.Add(pEnt);
finally
Unlock;
SaveFileExpEnt;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. AddFileExpEnt()');
end;
end;
procedure TManagerService.SaveFileExpEnt;
var
O, OA: ISuperObject;
i: Integer;
begin
try
OA := TSuperObject.Create(stArray);
Lock;
try
for i := 0 to FileExpEntList_.Count - 1 do
OA.AsArray.Add(TTgJson.ValueToJsonObject<TFileExpEnt>(FileExpEntList_[i]^));
finally
Unlock;
end;
O := SO;
O.O['List'] := OA;
SaveJsonObjToEncFile(O, GetRunExePathDir + DIR_CONF + DAT_FILEEXP, PASS_STRENC);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SaveFileExpEnt()');
end;
end;
procedure TManagerService.LoadFileExpEnt;
var
sPath: String;
O: ISuperObject;
i: Integer;
pEnt: PFileExpEnt;
begin
try
Lock;
try
FileExpEntList_.Clear;
finally
Unlock;
end;
sPath := GetRunExePathDir + DIR_CONF + DAT_FILEEXP;
if LoadJsonObjFromEncFile(O, sPath, PASS_STRENC) then
begin
if (O.O['List'] = nil) or (O.O['List'].DataType <> stArray) then
exit;
Lock;
try
for i := 0 to O.A['List'].Length - 1 do
begin
New(pEnt);
pEnt^ := TTgJson.GetDataAsType<TFileExpEnt>(O.A['List'].O[i]);
FileExpEntList_.Add(pEnt);
end;
finally
Unlock;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. LoadFileExpEnt()');
end;
end;
procedure TManagerService.OrganizeFileExpEnt;
var
i, nLimitMin: Integer;
pEnt: PFileExpEnt;
dwNow: TDateTime;
bSave: Boolean;
begin
try
bSave := false;
dwNow := Now;
nLimitMin := PrefModel_.FileExpMin;
Lock;
try
for i := FileExpEntList_.Count - 1 downto 0 do
begin
pEnt := FileExpEntList_[i];
if MinutesBetween(pEnt.dtReg, dwNow) >= nLimitMin then
begin
FileExpEntList_.Delete(i);
bSave := true;
end;
end;
finally
Unlock;
end;
if bSave then
SaveFileExpEnt;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OrganizeFileExpEnt()');
end;
end;
function TManagerService.HasFileExp(sPath: String): Boolean;
var
i: Integer;
pEnt: PFileExpEnt;
bOutlook: Boolean;
StrList: TStringList;
sHash: String;
begin
Result := false;
StrList := nil;
bOutlook := Pos('|', sPath) > 0;
if bOutlook then
begin
// 아웃룩 첨부 확인 추가 25_1112 14:58:02 kku
StrList := TStringList.Create;
SplitString(sPath, '|', StrList);
if StrList.Count <= 1 then
begin
// 서명, 본문 이미지의 경우 해시값이 없이 들어온다, 이 경우 예외 처리 25_1203 11:01:18 kku
Result := true;
exit;
end;
sHash := StrList[0];
var sExt: String := GetFileExt(sHash).ToUpper;
// 서명등 본문에 들어가는 이미지를 식별해서 예외 25_1203 10:49:17 kku
if sHash.ToLower.StartsWith('image0') and
( (sExt = 'PNG') or (sExt = 'JPG') or (sExt = 'JPEG') or (sExt = 'BMP')) then
Exit(true);
sHash := StrList[1];
end else begin
if not FileExists(sPath) then
exit;
sHash := GetFileToSha1Str_BS1(sPath);
end;
_Trace('HasFileExp() .. Path=%s, Hash=%s, FileExpCount=%d', [sPath, sHash, FileExpEntList_.Count], 5);
Lock;
try
for i := 0 to FileExpEntList_.Count - 1 do
begin
pEnt := FileExpEntList_[i];
// if bOutlook then
// begin
// if (CompareText(StrList[0], pEnt.sPath) = 0) and
// (CompareText(StrList[1], pEnt.sHash) = 0) then
// begin
// Result := true;
// exit;
// end;
// end else
// if (CompareText(sPath, pEnt.sPath) = 0) and
// (CompareText(GetFileToSha1Str(sPath), pEnt.sHash) = 0) then
// begin
// Result := true;
// exit;
// end;
if CompareText(sHash, pEnt.sHash) = 0 then
begin
_Trace('HasFileExp() .. Found', 5);
Result := true;
exit;
end;
end;
finally
Unlock;
end;
end;
procedure TManagerService.DoPrint(pEnt: PPrtEnt);
function GetPrintLog: ISuperObject;
var
O, OSub, OLog: ISuperObject;
sCompId: String;
sMsg: String;
PO: TPrefModel;
dt: TDateTime;
begin
Result := nil;
try
sMsg := Format('Printer : %s, Document : %s', [pEnt.WInfo.sPtrName, pEnt.WInfo.sDocName]);
PO := GetModePolicy;
dt := Now;
O := SO;
O.S['TYP_MSG'] := '@(!)_IC_P';
O.S['KEY_AGENTID'] := sAgentId_;
O.S['KEY_EMPNO'] := sEmpNo_;
O.S['KEY_HOSTNAME'] := sUserName_;
O.S['KEY_SUBMITTIME'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dt);
O.S['key_submitTime'] := FormatDateTime('yyyy-MM-dd"T"hh:nn:ss.zzz', dt) + sUtcOffset_;
O.S['KEY_LOGCODE'] := LOGCODE_EVENT_PRINTER;
O.S['DETECTION_DATE'] := O.S['KEY_SUBMITTIME']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['detectionDate'] := O.S['key_submitTime']; // 이벤트 발생 시각. REQUEST의 경우, 예외 신청할 이벤트의 발생 시각
O.S['KEY_SUMMARY'] := sMsg;
// O.S['PARENT_LA_ID'] // 상위 이벤트
O.S['POLICY_ID'] := PO.PolicyId;
// O.S['POLICY_KEY'] // 정책 위반한 경우 (PREVENT, MONITOR), 위반한 정책의 정책 키 값, 수집인 경우 (DEPLOY), 수집 요청 ID
if PO.Print.bCollectOutput then
begin
O.S['MESSAGE_BODY'] := pEnt.sText; // 정책 위반한 경우 (PREVENT, MONITOR), 원문 (본문) 컨텐츠, 수집인 경우 (DEPLOY), 수집 결과 내용, 원문 수집 정책이 비활성화인경우 수집하지 않음
O.S['OCR_BODY'] := pEnt.sOcrText; // 이미지 OCR 추출된 컨텐츠, 원문 수집 정책이 비활성화인 경우 수집하지 않음
end;
if pEnt.sVioText <> '' then
O.S['RULE_VIOLATED'] := pEnt.sVioText; // 정책 위반 규칙과 위반 개수. (LIST)
if FileExists(pEnt.sFPath) then
begin
if PO.Print.bCollectFile then
begin
sCompId := MakeComponentId(ExtractFileName(pEnt.sFPath));
// SendFile(sCompId, 'printLogCollect.do', sDocPath); // 원본 파일 수집은 이걸로 하면 안됨 24_0122 16:52:00 kku
SendFileNor(false, sCompId, 'quarantineLogCollect.do', pEnt.sFPath, PO.PrtMinMB, PO.PrtMaxMB);
O.S['COMPONENT_ID'] := sCompId; // 파일 고유값. 에이전트에서 임의 생성. (이벤트간 동일 파일 판단은 서버에서 하겠습니다.)
end;
O.S['COMPONENT_FILENAME'] := ExtractFileName(pEnt.sFPath); // 파일명
O.S['COMPONENT_PATH'] := ExtractFilePath(pEnt.sFPath);// 파일 절대 경로
var dtCreate, dtModify, dtAccess: TDateTime;
GetFileDateTime_Local(pEnt.sFPath, dtCreate, dtModify, dtAccess);
var dwAttr: DWORD := GetFileAttributes(PChar(pEnt.sFPath));
var OTemp: ISuperObject := SO;
OTemp.S['FILESIZE'] := IntToStr(GetFileSize_path(pEnt.sFPath));
OTemp.S['LASTMODIFIED'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtModify);
if dwAttr <> DWORD(-1) then
OTemp.S['READONLY'] := BooleanToStr((dwAttr and FILE_ATTRIBUTE_READONLY) <> 0, 'true', 'false');
if dwAttr <> DWORD(-1) then
OTemp.S['HIDDEN'] := BooleanToStr((dwAttr and FILE_ATTRIBUTE_HIDDEN) <> 0, 'true', 'false');
// OTemp.S['AUTHOR'] // {만든 이}
// OTemp.S['LASTUSER'] // {마지막으로 저장한 사람}
// OTemp.S['FILETYPE'] // {컨텐츠 타입}
// OTemp.S['FILECLS'] // {컨텐츠 형식}
// OTemp.S['PASSWORD'] // {암호적용여부}
// OTemp.S['ENCRYPTED'] := BooleanToStr(pInfo.bDrm, 'true', 'false');
// OTemp.S['CORRUPT'] // {깨진파일/정상파일여부}
O.O['COMPONENT_METADATA'] := OTemp;
O.S['COMPONENT_LASTACCESS'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtAccess);
end;
O.S['COMPONENT_THUMBNAIL_ID'] := pEnt.sThumbIds; // 이미지 미리보기 혹은 이미지가 있는경우, 이미지 파일의 파일 고유값. (출력물의 경우 첫 3장 이미지, 캡쳐 이미지 등), 복수개 허용, ";" 구분
// O.S['APPLICATION_NAME'] := sPName; // 사용 APP 이름
// O.S['APPLICATION_PATH'] := sPPath;// 사용 APP 절대 경로 (실행 파일 exe의 절대 경로)
O.S['PRINTER_JOBNAME'] := pEnt.WInfo.sDocName;
if pEnt.WInfo.bUseWM then
O.S['RESPONSE_INFO'] := 'WATERMARK';
// OSub.S['PAPERINFO'] := pEnt.WInfo.OLog;
O.S['DESTINATION_PORT'] := pEnt.WInfo.sPrtIp;
OSub := SO;
OSub.S['PAGEINFO'] := Format('%d/%d', [pEnt.WInfo.dwTotalPage, pEnt.WInfo.dwTotalPage]);
OSub.S['COLOR'] := BooleanToStr(pEnt.WInfo.bColor, 'true', 'false');
OSub.S['WARTERMARK'] := BooleanToStr(pEnt.WInfo.bUseWM, 'true', 'false');
OSub.S['PAPERINFO'] := pEnt.WInfo.sPaperInfo;
O.O['PRINTER_METADATA'] := OSub; // '{"PAGEINFO": "2/2", "COLOR": "true", "WARTERMARK": "false"}';
O.S['REMOVABLE_NAME'] := pEnt.WInfo.sPtrName; // USB등과 같은 매체 혹은 프린터 등과 같은 외부 장치 이름
O.S['actionGroupId'] := pEnt.WInfo.sPrtDocId; // 문서번호
O.I['printCopyCnt'] := pEnt.WInfo.dwCopy; // 부수
O.I['printPageCnt'] := pEnt.WInfo.dwTotalPage; // 장수
Result := O;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SendEventLog()');
end;
end;
var
sConv,
sEmfZip,
sEmfDir,
sSplPath,
sDecPath,
sExportPath: String;
dec : TTgDrmDec;
bDecResult: Boolean;
begin
try
sConv := GetRunExePathDir + DIR_CONF + EXE_SPL;
if not FileExists(sConv) then
begin
_Trace('Fail .. DoPrint() .. NotFoundConv');
exit;
end;
// 최대 출력수 확인
// if pEnt.nPrtCnt > 3 then
// begin
// MgPrint_.DelPrintInfo(pEnt.sId, true);
// exit;
// end;
//
// Inc(pEnt.nPrtCnt);
// MgPrint_.Save;
sEmfZip := MgPrint_.DataDir + pEnt.sId + '.dat';
if FileExists(sEmfZip) then
begin
var zip: TZipFile;
Guard(zip, TZipFile.Create);
zip.Open(sEmfZip, zmRead);
sEmfDir := MgPrint_.DataDir + pEnt.sId + '\';
if not ForceDirectories(sEmfDir) then
begin
_Trace('Fail .. DoPrint() .. CreateDir(zip)');
exit;
end;
zip.ExtractAll(sEmfDir);
SendMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 1,
NativeUInt(PChar(IntToStr(pEnt.WInfo.dwTotalPage) + '|' + ExtractFilePath(sDecPath) + '|' + pEnt.sFPath)));
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 1, 0);
TThdExecuteEndNoti.Create(hRcvHwnd_, GetPrintLog, pEnt, '', '', '', '', nil).StartThread;
// SendMessage(hRcvHwnd_, WM_NOTIEXECUTE_END, 1, NativeUInt(pEnt));
end else begin
// 복호화 24_1002 15:37:38 kku
sSplPath := MgPrint_.DataDir + pEnt.sId + '.pdt';
sDecPath := MgPrint_.DataDir + pEnt.sId + '\Tdel.dsp';
if not ForceDirectories(ExtractFilePath(sDecPath)) then
begin
_Trace('Fail .. DoPrint() .. MakeTaskDir');
exit;
end;
dec := TTgDrmDec.Create(sSplPath);
bDecResult := true;
try
if not dec.CheckSig(SIG_DRM) then
bDecResult := false;
if bDecResult and not dec.ExtrHead(PASS_DRM_HEAD) then
bDecResult := false;
if bDecResult and (dec.Head.dwCustomerCode <> CUSTOMER_TYPE) then
bDecResult := false;
// todo : 권한 체크
if bDecResult then
begin
// 암호화 대응 제외
gMgSvc.AddEncIgr(sDecPath);
bDecResult := dec.DecryptToFile(GetMK + '&PtR', sDecPath);
end;
finally
FreeAndNil(dec);
end;
if not bDecResult then
begin
_Trace('Fail .. DoPrint() .. DecryptSpool');
exit;
end;
sExportPath := ExtractFilePath(sDecPath) + ExtractFileName(pEnt.sFPath) + '.png';
// {$IFNDEF DEBUG}
if IsPrtSpl2Pdf then
begin
case CUSTOMER_TYPE of
CUSTOMER_SHCI,
CUSTOMER_SHSC :
begin
if (CompareText('InsideBank.exe', pEnt.sPName) <> 0) and
(CompareText('excel.exe', pEnt.sPName) <> 0) and
(CompareText('POWERPNT.EXE', pEnt.sPName) <> 0) and
(CompareText('Hwp.exe', pEnt.sPName) <> 0) then
sExportPath := CutFileExt(sExportPath) + '.pdf';
end;
// CUSTOMER_SHCI :
// begin
// if (CompareText('InsideBank.exe', pEnt.sPName) <> 0) and
// (CompareText('Hwp.exe', pEnt.sPName) <> 0) then
// sExportPath := CutFileExt(sExportPath) + '.pdf';
// end;
end;
end;
// {$ENDIF}
SendMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 1,
NativeUInt(PChar(IntToStr(pEnt.WInfo.dwTotalPage) + '|' + ExtractFilePath(sDecPath) + '|' + pEnt.sFPath)));
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 1, 0);
var sParam: String := Format('-$ 65XSD4234455S4PLET58 -unicode -imgbitcount 24 -imgxres %d -imgyres %d', [PrefModel_.PrtDPI, PrefModel_.PrtDPI]) + ' "%s" "%s"';
TThdExecuteEndNoti.Create(hRcvHwnd_, GetPrintLog, pEnt, sConv, sParam, sDecPath, sExportPath, nil).StartThread;
// SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 2, 0);
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoPrint()');
end;
end;
procedure TManagerService.StartCampaignTask(pCamEnt: PCampnEnt);
var
Opt: TFileScanOpt;
DrvList: TStringList;
i: Integer;
DrvEx: TTgDriveExtent;
sInfoDir: String;
PO: TPrefModel;
bContinue: Boolean;
begin
//exit;
try
if pCamEnt = nil then
exit;
if pProcCampn_ <> nil then
exit;
if ThdScanSch_ <> nil then
FreeAndNil(ThdScanSch_);
{$IFNDEF DEBUG}
// 프로그램 시작 후 30초 후에 동작하도록 보완 24_0516 09:47:58 kku
if SecondsBetween(dtCreateMg_, Now) < 30 then
exit;
{$ENDIF}
if CUSTOMER_TYPE = CUSTOMER_DEV then
begin
if bFirstAip_ then
FindAipMdWnd;
end else
if IsSupportAIP then
FindAipMdWnd;
if pCamEnt.Info.CampnType = ctVul then
begin
// 현재 지원하지 않음 23_1113 13:04:17 kku
pCamEnt.dtLastWork := Now;
MgCampn_.Save;
exit;
end;
// sInfoDir := ExtractFilePath(pCamEnt.sSchRstPath);
//// if pCamEnt.Info.CampnType <> ctScanPatial then // 증분 검사 시 이전기록 삭제안하게 23_1122 15:08:26 kku
// begin
// if (sInfoDir <> '') and DirectoryExists(sInfoDir) then
// DeleteDir(sInfoDir);
// end;
pCamEnt.sSchRstPath := '';
pCamEnt.sSchRstExpPath := '';
NoMatchList_.Clear;
PO := GetModePolicy;
bIsStopCampn_ := false;
llCampnEncCnt_ := 0;
llCampnEncFailCnt_ := 0;
ZeroMemory(@Opt, SizeOf(Opt));
Opt.sSchPtrns := '<Empty>'; // 이거 비어 있으면 ptnsch.dat 파일에서 체크된 항목 검사됨
Opt.sScanId := pCamEnt.Info.sId;
Opt.sSchTitle := pCamEnt.Info.sName;
Opt.bShowSchTitle := pCamEnt.Info.bShowScan;
Opt.nLimitSizeMB := pCamEnt.Info.nLimitSizeMB; // PO.CfLimitMB;
Opt.nSchTimeoutSec := pCamEnt.Info.nTimeoutSec; // PO.CfTimeoutSec;
Opt.sIgrWordPath := pCamEnt.Info.sExpFolders;
Opt.bPartScan := pCamEnt.Info.CampnType = ctScanPatial;
Opt.dtRecent := pCamEnt.dtLastWork;
Opt.sScanExt := pCamEnt.Info.sExts;
if Opt.sScanExt = '' then
Opt.sScanExt := DOC_EXTS;
Opt.sTgDirs := pCamEnt.Info.sTgFolders;
if Opt.sTgDirs = '' then
begin
Opt.sTgDirs := GetDrivesFromMask(GetLogicalDrives, false, true);
if Opt.sTgDirs = '' then
begin
_Trace('Fail .. StartCampaignTask(), Not found drive');
exit;
end;
Guard(DrvEx, TTgDriveExtent.Create);
Guard(DrvList, TStringList.Create);
SplitString(Opt.sTgDirs, ',', DrvList);
Opt.sTgDirs := '';
for i := 0 to DrvList.Count - 1 do
begin
if GetDriveExtent(DrvList[i]).liExtentLength.QuadPart <> 0 then
SumString(Opt.sTgDirs, DrvList[i], '|');
end;
if Opt.sTgDirs = '' then
begin
_Trace('Fail .. StartCampaignTask(), Not found drive 2');
exit;
end;
end;
Opt.nLangId := 1;
Opt.CttSchOpt.nUnzipDepth := PO.CfZipDepth;
Opt.CttSchOpt.hRcvHwnd := hRcvHwnd_;
Opt.CttSchOpt.nWorkPriority := -1;
Opt.CttSchOpt.sKvMdPath := GetRunExePathDir + 'bin\';
Opt.CttSchOpt.nKvTimeoutSec := Opt.nSchTimeoutSec;
Opt.CttSchOpt.sMK := GetMK(false);
Opt.CttSchOpt.bIncFName := pCamEnt.Info.bIncFName;
Opt.CttSchOpt.bIncZip := pCamEnt.Info.bDecompress and (pCamEnt.Info.CampnType <> ctForceEnc);
Opt.CttSchOpt.nAipEncMSec := PrefModel_.AipEncMSec;
if Opt.CttSchOpt.bIncZip then
Opt.CttSchOpt.sZipExts := Opt.sScanExt;
// SumString(Opt.sScanExt, COMPRESS_EXTS, '|');
Opt.CttSchOpt.bIncDrm := true; // todo : DRM 옵션 추가 필요 23_1024 09:25:42 kku
if pCamEnt.Info.CampnType = ctForceEnc then
begin
Opt.CttSchOpt.sSchTxt := '|*FORCEDRM*|';
Opt.nLimitSizeMB := 0; // 암호화는 제한없음
Opt.nSchTimeoutSec := 300; // 암호화는 5분 고정
Opt.CttSchOpt.nKvTimeoutSec := Opt.nSchTimeoutSec;
pCamEnt.Info.Respaction := crtDRM;
if IsUseEncOnlyAIP then
begin
pCamEnt.Info.Respaction := crtAIP
end else
if IsSupportAIP then
begin
if bFirstAip_ then
pCamEnt.Info.Respaction := crtAIP;
end;
end;
if IsSupportAIP then
begin
Opt.CttSchOpt.sAipMdPath := GetAipPath;
Opt.CttSchOpt.sAipDMail := sAccount_;
Opt.CttSchOpt.sAipPxMail := sEmail_;
Opt.CttSchOpt.sAipExt := AIP_EXTS;
end;
case pCamEnt.Info.Respaction of
crtAIP :
begin
if Opt.CttSchOpt.sAipLabelId = '' then
Opt.CttSchOpt.sAipLabelId := GetDefAipLabelId(pCamEnt.Info.CampnType = ctForceEnc);
// Opt.CttSchOpt.sTaskDir := 'C:\ProgramData\HE\Task\';
Opt.CttSchOpt.bMakeDrm := Opt.CttSchOpt.sAipMdPath <> '';
Opt.CttSchOpt.bMakeDrmN := pCamEnt.Info.bNoFindEnc;
end;
crtDRM :
begin
if not NotUseDRM then
begin
Opt.CttSchOpt.sAipMdPath := '';
var sDept: String := '';
if sDeptName_ <> '' then
sDept := sDeptName_
else if PrefModel_.DeptName <> '' then
sDept := PrefModel_.DeptName;
Opt.CttSchOpt.sAipDMail := Format('%s|%s|%s|%s|%d', [sEmpNo_, sUserName_, sDept, PrefModel_.PolicyName, CUSTOMER_TYPE]);
Opt.CttSchOpt.bMakeDrm := true;
end else
if (CUSTOMER_TYPE = CUSTOMER_LOTTEMART) or (CUSTOMER_TYPE = CUSTOMER_WELFNI) or (CUSTOMER_TYPE = CUSTOMER_WELFND) then
Opt.CttSchOpt.bMakeDrm := true;
end;
end;
if pCamEnt.Info.bUseFilter then
begin
_Trace('StartCampaignTask() .. CRList=%s', [pCamEnt.Info.sCRList], 9);
Opt.CttSchOpt.sCustomKwdPtrn := MgRule_.GetRuleSearchStrFromIds(pCamEnt.Info.sCRList);
_Trace('StartCampaignTask() .. Ptrn=%s', [Opt.CttSchOpt.sCustomKwdPtrn], 9);
end;
Opt.CttSchOpt.bExtrTxt := pCamEnt.Info.bGetContents;
sInfoDir := GetRunExePathDir + DIR_CTTSCHRST;
pCamEnt.sSchRstPath := sInfoDir + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHRSTDATA]);
pCamEnt.sSchRstExpPath := sInfoDir + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHRSTDATA_EXP]);
// 증분검사, 기존결과유지 사용 시 활성화 되서 검출되지 않은 파일 정보 전달 24_0611 08:50:05 kku
Opt.CttSchOpt.bNoMatchNoti := (pCamEnt.Info.CampnType = ctScanPatial) and pCamEnt.Info.bIncOldRst and FileExists(pCamEnt.sSchRstPath);
bContinue := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'cppn') <> '';
if (pCamEnt.Info.CampnType <> ctForceEnc) and DirectoryExists(sInfoDir) then
begin
if not bContinue then //진행중 값이 있을때 지우지 않는다 25_0515 16:19:37 kku
begin
if (pCamEnt.Info.CampnType = ctScanPatial) and pCamEnt.Info.bIncOldRst then
begin
var sBkPath: String := GetRunExePathDir + DIR_CTTSCHRST_BACKUP;
if not FileExists(sBkPath) and ForceDirectories(sBkPath) then
begin
// 검색중 재부팅 가능성이 있기 때문에 이전 파일을 확인해준다. 24_0423 11:07:06 kku
var sSchRstPathBk: String := sBkPath + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHRSTDATA]);
var sInfoPathBk: String := sBkPath + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHRST]);
// 증분 검사 시 이전 기록 백업 후 재사용 24_0423 10:45:32 kku
if FileExists(pCamEnt.sSchRstPath) and not FileExists(sSchRstPathBk) then
CopyFile(PChar(pCamEnt.sSchRstPath), PChar(sSchRstPathBk), true);
var sInfoPath: String := sInfoDir + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHRST]);
if FileExists(sInfoPath) and not FileExists(sInfoPathBk) then
CopyFile(PChar(sInfoPath), PChar(sInfoPathBk), true);
end;
end;
DeleteDir(sInfoDir);
end;
end;
if not ForceDirectories(sInfoDir) then
_Trace('Fail .. Create sch workdir ..');
// DeleteFile(PChar(pCamEnt.sSchRstPath));
// DeleteFile(PChar(pCamEnt.sSchRstExpPath));
if not FileExists(sInfoDir + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHOPT])) then
begin
// DeleteFile(PChar(Format('%s%s.%s', [sInfoDir, aOpt.sScanId, DAT_CTTSCHRST])));
// DeleteFile(PChar(Format('%s%s.%s', [sInfoDir, aOpt.sScanId, DAT_CTTSCHRSTDATA])));
// DeleteFile(PChar(Format('%s%s.%s', [sInfoDir, aOpt.sScanId, DAT_CTTSCHOPT])));
SaveJsonObjToEncFile(TTgJson.ValueToJsonObject<TFileScanOpt>(Opt),
sInfoDir + Format('%s.%s', [Opt.sScanId, DAT_CTTSCHOPT]), PASS_STRENC);
end;
pProcCampn_ := pCamEnt;
ThdScanSch_ := TThdSchFileScan.Create(Opt.sTgDirs, Opt, 0, true);
ThdScanSch_.OnScanSearchBegin := OnCampaignTaskBegin;
ThdScanSch_.OnScanSearchEnd := OnCampaignTaskEnd;
case CUSTOMER_TYPE of
CUSTOMER_DEV : ThdScanSch_.IgrAipDrm := pCamEnt.Info.CampnType = ctForceEnc;
CUSTOMER_SHSC,
CUSTOMER_SHCI,
CUSTOMER_GEC,
CUSTOMER_HDENG :
begin
ThdScanSch_.IgrScDrm := pCamEnt.Info.CampnType = ctForceEnc;
ThdScanSch_.IgrAipDrm := pCamEnt.Info.CampnType = ctForceEnc;
end;
// CUSTOMER_HAE : ThdScanSch_.IgrScDrm := true;
CUSTOMER_HCA : ThdScanSch_.IgrScDrm := true;
end;
if UseFasooDecrypt then
ThdScanSch_.IgrFasDrm := pCamEnt.Info.CampnType = ctForceEnc;
ThdScanSch_.IgrAipDrm := IsSupportAIP and (pCamEnt.Info.CampnType = ctForceEnc);
ThdScanSch_.IgrExcept := true;
if Opt.CttSchOpt.bIncFName then
ThdScanSch_.IgrSizeZero := false
else
ThdScanSch_.IgrSizeZero := not Opt.CttSchOpt.bNoMatchNoti;
ThdScanSch_.StartThread;
RefreshView;
if pProcCampn_.Info.bShowScan then
begin
if not bContinue then
begin
case pCamEnt.Info.CampnType of
ctScan,
ctScanPatial :
begin
if CUSTOMER_TYPE = CUSTOMER_HDENG then
begin
if GetHecVer = 2 then
PopupMessage(TYPE_MSG_CTTSCH_START);
end else
PopupMessage(TYPE_MSG_CTTSCH_START);
end;
ctForceEnc :
begin
// if not IsHD then // HEC에서 숨김
PopupMessage(TYPE_MSG_CAMPN_FILEENC);
end;
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. StartCampaignTask()');
end;
end;
procedure TManagerService.StopCampaignTask;
begin
try
if ThdScanSch_ <> nil then
begin
if pProcCampn_ <> nil then
begin
pProcCampn_.dtLastWork := Now;
pProcCampn_.dtLastNoti := pProcCampn_.dtLastWork;
MgCampn_.Save;
pProcCampn_ := nil;
NoMatchList_.Clear;
end;
bIsStopCampn_ := true;
llCampnEncCnt_ := ThdScanSch_.TotalEncCount;
llCampnEncFailCnt_ := ThdScanSch_.TotalEncFailCount;
FreeAndNil(ThdScanSch_);
if MgFnd_ <> nil then
FreeAndNil(MgFnd_);
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cppn');
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cptd');
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cpid');
RefreshView;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. StopPiSchTask()');
end;
end;
procedure TManagerService.OnCampaignTaskBegin(aSender: TObject);
begin
if MgFnd_ <> nil then
FreeAndNil(MgFnd_);
{$IFDEF DEBUG} DeleteFile(PChar(GetRunExePathDir + JSON_PI_TEST)); {$ENDIF}
MgFnd_ := TManagerFound.Create;
end;
procedure TManagerService.OnCampaignTaskEnd(aSender: TObject);
var
dtEnd: TDateTime;
O, OA: ISuperObject;
sCurDir,
sScanId,
sPath,
sTime,
sResult: String;
bClearData: Boolean;
nFoundFileCnt: Integer;
ScanBlockKind: TScanBlockKind;
nPersonalInfoFileMax: Integer;
begin
try
if ThdScanSch_ = nil then
exit;
if pProcCampn_ = nil then
begin
_Trace('Fail .. OnCampaignTaskEnd() .. Invalid Campaign info ..');
exit;
end;
sScanId := ThdScanSch_.CttSchProg.sScanId;
dtEnd := Now;
sTime := ConvSecBetweenToProgTime(ThdScanSch_.BeginDT, dtEnd);
O := SO;
O.S['ID'] := sScanId;
O.S['TID'] := ThdScanSch_.CttSchProg.sTaskId;
O.S['BeginDT'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', ThdScanSch_.BeginDT);
O.S['EndDT'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', dtEnd);
O.I['WorkSec'] := SecondsBetween(ThdScanSch_.BeginDT, dtEnd);
O.S['WorkTime'] := sTime;
O.I['TotalFileCount'] := ThdScanSch_.TotalFileCount;
O.I['TargetFileCount'] := ThdScanSch_.TotalTgFileCount;
O.I['FoundFileCount'] := ThdScanSch_.FoundFileCount;
O.I['EncFileCount'] := ThdScanSch_.TotalEncCount;
O.S['FoundSInfo'] := MgFnd_.ToEntInfoStr;
O.O['FoundInfo'] := MgFnd_.ToJsonObj;
sCurDir := GetRunExePathDir;
{$IFDEF DEBUG} SaveJsonObjToFile(O, sCurDir + JSON_PI_TEST); {$ENDIF}
sResult := MgFnd_.ToEntInfoStr;
if ForceDirectories(sCurDir + DIR_CTTSCHRST) then
begin
if sScanId <> '' then
SaveJsonObjToFile(O, Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHRST]))
else
SaveJsonObjToFile(O, sCurDir + DIR_CTTSCHRST + DAT_CTTSCHRST);
nFoundFileCnt := ThdScanSch_.FoundFileCount - ThdScanSch_.TotalEncCount - ThdScanSch_.TotalDelCount;
_Trace('OnCampaignTaskEnd() .. Found=%d, Enc=%d, Del=%d, Result=%d', [ThdScanSch_.FoundFileCount, ThdScanSch_.TotalEncCount, ThdScanSch_.TotalDelCount, nFoundFileCnt]);
if gMgSvc.IsNewApi and (pProcCampn_.Info.CampnType = ctScanPatial) then
begin
var sBkPath: String := GetRunExePathDir + DIR_CTTSCHRST_BACKUP;
if DirectoryExists(sBkPath) then
begin
if pProcCampn_.Info.bIncOldRst then
begin
// 개인정보 증분검사 라면 이전 데이터 확인해서 합치도록 기능 추가 24_0423 13:36:35 kku
nFoundFileCnt := ProcessMergeCampaignBkData(O);
end;
DeleteDir(sBkPath);
end;
end;
// 캠페인 시작 팝업 있으면 닫기
var h: HWND := FindWindow('TDlgNoticeImg', nil);
if h <> 0 then
PostMessage(h, WM_CLOSE, 0, 0);
if pProcCampn_.Info.bShowScan then
begin
// if pProcCampn_.Info.bPopupResult then
case pProcCampn_.Info.CampnType of
ctScan :
begin
if pProcCampn_.Info.nNotiIfCnt <= nFoundFileCnt then
PopupMessage(TYPE_MSG_CTTSCH_COMPLETE, sTime + '|' + IntToStr(nFoundFileCnt));
end;
ctScanPatial :
begin
if pProcCampn_.Info.bIncOldRst then
begin
var nRCnt: Integer := GetExistPiFileCount(pProcCampn_.Info.sId);
_Trace('OnCampaignTaskEnd(), FCnt=%d, RCnt=%d', [nFoundFileCnt, nRCnt], 1);
PopupMessage(TYPE_MSG_CTTSCH_COMPLETE, sTime + '|' + IntToStr(nRCnt));
end else
if pProcCampn_.Info.nNotiIfCnt <= nFoundFileCnt then
PopupMessage(TYPE_MSG_CTTSCH_COMPLETE, sTime + '|' + IntToStr(nFoundFileCnt));
end;
end;
end;
end;
bClearData := pProcCampn_.Info.CampnType = ctForceEnc;
// ScanBlockKind := PrefModel_.ScanBlockKind;
// nPersonalInfoFileMax := PrefModel_.PersonalInfoFileMax;
// if sScanId <> '' then
// begin
// ThdScanSch_.UpdateProgress('complete', true, sResult);
// MgCttSch_.CompleteTask(sScanId, ThdScanSch_.ScanDate);
//
// if (nPersonalInfoFileMax > 0) and
// (nPersonalInfoFileMax <= ThdScanSch_.FoundFileCount) then
// begin
// SetSchRstVul(true);
// bClearData := false;
// SendEventLog(URI_USER_ACTION, STATUS_FILESCAN,
// Format('Found=%d, File=%d', [ThdScanSch_.FoundCount, ThdScanSch_.FoundFileCount]));
//
// PopupMessage(TYPE_MSG_CTTSCH_VULMODE);
// end;
// end;
// if nPersonalInfoFileMax = 0 then
// begin
// DeleteDir(sCurDir + DIR_CTTSCHRST);
// end else
if bClearData then
begin
DeleteFile(PChar(Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHRST])));
DeleteFile(PChar(Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHRSTDATA])));
DeleteFile(PChar(Format('%s%s.%s', [sCurDir + DIR_CTTSCHRST, sScanId, DAT_CTTSCHOPT])));
end;
// if bSchRstVul_ and (GetPersonalInfoResults = 0) then
// SetSchRstVul(false);
{$IFDEF DEBUG}
sPath := GetRunExePathDir + 'PersonalInfo.txt';
if FileExists(sPath) then
DeleteFile(PChar(sPath));
WriteLnFileEndUTF8(sPath, sResult);
{$ENDIF}
if sScanId <> '' then
_Trace('OnCampaignTaskEnd() End .. Campaign ID=%s', [sScanId]);
if MgFnd_ <> nil then
FreeAndNil(MgFnd_);
pProcCampn_.dtLastWork := Now;
pProcCampn_.dtLastNoti := pProcCampn_.dtLastWork;
if pProcCampn_.Info.bNoActionVul then
UpdateCttSchVulState(true);
MgCampn_.Save;
pProcCampn_ := nil;
NoMatchList_.Clear;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CampaignTaskEnd()');
end;
llCampnEncCnt_ := ThdScanSch_.TotalEncCount;
llCampnEncFailCnt_ := ThdScanSch_.TotalEncFailCount;
bTerminateThdScanSch_ := true;
RefreshView;
end;
function TManagerService.IsScreenLogo: Boolean;
begin
Result := bForceScreenLogo_ or (ModePolicy.ScreenLogo = askAlways);
if not Result and (nMonitorCnt_ > 0) then
nMonitorCnt_ := 0;
end;
procedure TManagerService.SetExpPolicyActive(aFun: TExpFun);
var
O: ISuperObject;
begin
// if llChkTimeSec_ = -1 then
// exit;
try
if bIsExpPolicy_ then
exit;
// todo : 예외 정책 세팅
try
if PrefModel_.IsOldPolicy then
begin
if PrefModel_.ExpPolicy = '' then
begin
case GetModeKind of
hmkSleep : O := SO(PrefModel_.IdlPolicy);
hmkSecurity :
begin
O := PrefModel_.GetPrefModeToJsonObj;
if O = nil then
O := SO;
end;
hmkVulnerability : O := SO(PrefModel_.VulPolicy);
hmkOffline : O := SO(PrefModel_.OffPolicy);
else {$IFDEF DEBUG} ASSERT(false); {$ELSE} exit {$ENDIF};
end;
end else
O := SO(PrefModel_.ExpPolicy);
if aFun.bUsb then
O.S['mwOKey_OPTIONB'] := 'logonly';
if aFun.bMtp then
O.S['KEY_MTPBLOCK'] := 'logonly';
if aFun.bBT then
O.S['KEY_BLUETOOTHBLOCK'] := 'logonly';
if aFun.bWifi then
O.S['mwPKey_WIFIPREVENT'] := 'logonly';
if aFun.bCB then
O.S['mwPKey_CLIPBOARDENABLE'] := 'logonly';
ExpPolicy.SetPrefModel(O);
end else begin
if not PrefExpPolicy_.Loaded then
begin
case GetModeKind of
hmkSleep : O := PrefIdlModel_.GetPolicyToJsonObj;
hmkSecurity : O := PrefModel_.GetPolicyToJsonObj;
hmkVulnerability : O := PrefVulModel_.GetPolicyToJsonObj;
hmkOffline : O := PrefVulModel_.GetPolicyToJsonObj;
else {$IFDEF DEBUG} ASSERT(false); {$ELSE} exit {$ENDIF};
end;
O.S['sPoId_'] := 'TEMP';
O.S['PolicyId'] := 'TEMP';
if aFun.bUsb then
O.I['UsbBlockKind'] := Integer(ubkLog);
if aFun.bMtp then
O.I['MtpBlockKind'] := Integer(dbkLog);
if aFun.bBT then
O.I['BlueBlockKind'] := Integer(dbkLog);
if aFun.bWifi then
O.I['WifiCtrlKind'] := Integer(wckLog);
if aFun.bCB then
O.I['ClipBlockKind'] := Integer(cbkLog);
PrefExpPolicy_.SetPolicy('TEMP', O, false);
end;
end;
except
on E: Exception do
begin
ETgException.TraceException(Self, E, 'Fail .. SetExpPolicyActive() .. SetPrefModel()');
exit;
end;
end;
llChkTimeSec_ := 0;
nExpPoMin_ := aFun.nUseMin;
dtExpPoBegin_ := Now;
bIsExpPolicy_ := true;
ThdTaskTimer_.SetTask(TimerCheckExpPo, 1000, true);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. SetExpPolicyActive()');
end;
end;
procedure TManagerService.ClearExpPolicy;
begin
// 예외 정책이 초기화될 경우 끝내기 위해 추가 24_0711 09:38:19 kku
dtExpPoBegin_ := 0;
end;
procedure TManagerService.AddPrintWaterEnt(pWEnt: PPrtWaterEnt);
begin
qWaterEnts_.Enqueue(pWEnt);
end;
procedure TManagerService.ProcessPrintWaterEnt;
procedure ExtrPrintImgFiles(sImgPath: String; aList: TStrings);
var
sFName: string;
i: Integer;
begin
aList.Clear;
sFName := StringReplace(CutFileExt(sImgPath), '_0001', '', [rfReplaceAll]);
if not FileExists(sImgPath) and not FileExists(Format('%s_%.4d.png', [sFName, 1])) then
exit;
if FileExists(sImgPath) then
aList.Add(sImgPath);
i := 1;
while True do
begin
sImgPath := Format('%s_%.4d.png', [sFName, i]);
if FileExists(sImgPath) then
begin
if aList.IndexOf(sImgPath) = -1 then
aList.Add(sImgPath);
end else exit;
Inc(i);
end;
end;
{ Returns grayscale version of a color. }
function RgbToGray(C: TColor): TColor;
begin
C := Round(C and $FF * 0.3 + C and $00FF00 shr 8 * 0.59 + C shr 16 * 0.11);
Result := RGB(C, C, C);
end;
{ Converts whole PNG image to grayscale. }
procedure ToGrayscale(PNG: TPNGObject);
var
X, Y: Integer;
begin
for X := 0 to PNG.Width - 1 do
for Y := 0 to PNG.Height - 1 do
PNG.Pixels[X, Y] := RgbToGray(PNG.Pixels[X, Y]);
end;
const
WORD_GAP = ' ';
type
TProcType = (ptPng, ptPdf, ptEmf);
var
pInfo: PPrtWaterEnt;
WInfo: TPrtWaterEnt;
pi, i, nLeft, nTop, nW, nH: Integer;
ImgList: TStringList;
ProcType: TProcType;
bIsWatchPtr: Boolean;
png: TPngImage;
mf: TMetaFile;
// bmp: TBitmap;
bf: BLENDFUNCTION;
sExt,
sPrtDocId,
sImgDir,
sImgPath,
sWImgPath,
sTopText,
sBottomText: String;
bProcGrayW: Boolean;
fST: Double;
sOutCode: AnsiString;
OLog: ISuperObject;
PO: TPrefModel;
arrDevice, arrDriver, arrPort: array [0..255] of Char;
hDev: THandle;
DevMode: PDeviceMode;
OrgDevMode: TDeviceMode;
pdf: SynPdf.TPdfDocumentGDI;
pdfPage: SynPdf.TPdfPage;
bmpWaterP: TBitmap;
// ImgEn: TImageEn;
procedure DoMasking(pEnt: PMskEnt);
var
R: TRect;
i: Integer;
sText: String;
x, y: Integer;
begin
R.Left := pEnt.x;
R.Top := pEnt.y;
R.Width := pEnt.w;
R.Height := pEnt.h;
png.Canvas.Pen.Color := clWhite;
png.Canvas.Pen.Style := psSolid;
png.Canvas.Brush.Color := clWhite;
png.Canvas.Brush.Style := bsSolid;// bsBDiagonal;
png.Canvas.FillRect(R);
sText := 'Hidden by BSOne';
for i := 1 to 99 do
begin
png.Canvas.Font.Size := i;
if (png.Canvas.TextHeight(sText) - 1) >= (R.Height - 2) then
begin
break;
end;
end;
png.Canvas.TextRect(R, sText, [tfCenter, tfEndEllipsis, tfVerticalCenter]);
png.Canvas.Pen.Color := clBlack;
png.Canvas.Pen.Style := psDot;
png.Canvas.MoveTo(R.Left, R.Top);
png.Canvas.LineTo(R.Left + R.Width, R.Top);
png.Canvas.LineTo(R.Left + R.Width, R.Top + R.Height);
png.Canvas.LineTo(R.Left, R.Top + R.Height);
png.Canvas.LineTo(R.Left, R.Top);
end;
function MaskPrtST: Boolean;
var
sStKey, sStPng: String;
nResult: Integer;
begin
try
if not FileExists(GetRunExePathDir + DIR_CONF + DLL_ST) then
exit;
sStKey := GetRunExePathDir + DIR_CONF + DAT_SNAPTAGKEY_P;
if not FileExists(sStKey) then
begin
var StrList: TStringList;
Guard(StrList, TStringList.Create);
StrList.Text := ST_Key_S;
StrList.SaveToFile(sStKey, TEncoding.ANSI);
end;
sStPng := GetRunExePathDir + DIR_CONF + PNG_SNAPTAGDATA_PRT;
nResult := labGuardPS(sStKey, sStPng, 2, 1{3블루}, 1 {유저코드?},
FormatDateTime('yyyy/mm/dd hh:nn', Now), sOutCode);
Result := nResult = 0;
if not Result then
TTgTrace.T('Fail .. MaskPrtST() .. Snaptag .. code = %d', [nResult], 1);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. MaskPrtST()');
end;
end;
procedure ProcessSnaptag;
var
sStPng: String;
pngST: TPngImage;
nsX, nsY: Integer;
begin
if not IsUseSnaptag then
exit;
if not MaskPrtST then
exit;
try
if _bmpST = nil then
begin
sStPng := GetRunExePathDir + DIR_CONF + PNG_SNAPTAGDATA_PRT;
if FileExists(sStPng) then
begin
Guard(pngST, TPngImage.Create);
pngST.LoadFromFile(sStPng);
_bmpST := TBitmap.Create;
_bmpST.PixelFormat := pf4bit;
_bmpST.SetSize(png.Width div 5, png.Height div 5);
nsX := 0;
while nsX < (_bmpST.Width + pngST.Width) do
begin
nsY := 0;
while nsY < (_bmpST.Height + pngST.Height) do
begin
_bmpST.Canvas.Draw(nsX, nsY, pngST);
Inc(nsY, pngST.Height);
end;
Inc(nsX, pngST.Width);
end;
end;
end;
if _bmpST <> nil then
begin
// _bmpST.SaveToFile('C:\Users\kku\Desktop\이전 바탕화면\출력 추출 데이터\test.bmp');
var cTrMatrix: TColorMatrix;
ZeroMemory(@cTrMatrix, SizeOf(cTrMatrix));
// 회색
// cTrMatrix[0][0] := 0.299;
// cTrMatrix[0][1] := 0.299;
// cTrMatrix[0][2] := 0.299;
// cTrMatrix[1][0] := 0.587;
// cTrMatrix[1][1] := 0.587;
// cTrMatrix[1][2] := 0.587;
// cTrMatrix[2][0] := 0.114;
// cTrMatrix[2][1] := 0.114;
// cTrMatrix[2][2] := 0.114;
// cTrMatrix[3][3] := 0.10; // 투명도 1.0 ~ 2.22
// cTrMatrix[4][4] := 1.0;
cTrMatrix := MakeColorMatrix(0.2, 0.2, 0.2, fST);
DrawBitmapWaterEx(png.Canvas.Handle, 0, 0, _bmpST, @cTrMatrix, png.Width, png.Height);
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessSnaptag()');
end;
end;
Label
LB_DoPrintHere,
LB_CollatePng, LB_CollatePdf, LB_CollateEmf,
LB_Collate1;
begin
try
if FindWindow('TDlgWaitExtrProcPrt', nil) <> 0 then
exit;
if Printer.Printing then
exit;
if qWaterEnts_.Count = 0 then
exit;
pInfo := qWaterEnts_.Dequeue;
if pInfo = nil then
exit;
PO := GetModePolicy;
fST := 0.03;
if IsUseSnaptag then
begin
var sIni := GetProgramFilesDir + DIR_TG + INI_FORCEHE;
if FileExists(sIni) then
begin
var ini: TIniFile;
Guard(ini, TIniFile.Create(sIni));
fST := ini.ReadFloat('Force', 'StBold', fST);
end;
end;
bmpWaterP := nil;
sOutCode := '';
WInfo := pInfo^;
sExt := GetFileExt(WInfo.sImgPath).ToUpper;
if sExt = 'PDF' then
ProcType := ptPdf
else if sExt = 'EM1' then
ProcType := ptEmf
else
ProcType := ptPng;
sPrtDocId := WInfo.sPrtDocId;
if sPrtDocId = '' then
sPrtDocId := 'Unknown';
Dispose(pInfo);
if WInfo.LogJson <> '' then
OLog := SO(WInfo.LogJson)
else
OLog := nil;
// {$IFDEF DEBUG}
// var sExtDir: String := ExtractFilePath(WInfo.sImgPath);
// var sImgDir: String := 'C:\Users\kku\Desktop\OutSpoolImg';
// if DirectoryExists(sExtDir) and DirectoryExists(sImgDir) then
// begin
// DeleteDirSub(sImgDir);
// CopyDirSub(sExtDir, sImgDir);
// DeleteDir(sExtDir);
// end;
// exit;
// {$ENDIF}
OrgDevMode := TTgRtti.StrToSetType<TDeviceMode>(WInfo.DevMode);
if (CUSTOMER_TYPE = CUSTOMER_GEC) and (Pos('HP', WInfo.sPtrName) = 1) then
goto LB_DoPrintHere;
// if IsPrtSpl2Pdf then
// WInfo.bUseWM := false;
{$IFDEF DEBUG}
// if IsUserModePrint or IsPrtSpl2Pdf then
// if IsPrtSpl2Pdf then
// if false then
if true then
{$ELSE}
// if IsUserModePrint and ((WInfo.sPdfPath = '') or IsPrtSpl2Pdf) then
if IsUserModePrint or IsPrtSpl2Pdf then
{$ENDIF}
begin
// 티맵에서 시스템 권한으로 프린트 요청 시 차단된다 24_0119 10:39:58 kku
var sKvCsPath: String := GetRunExePathDir + EXE_KVCTTSCH;
if FileExists(sKvCsPath) then
begin
_Trace('외부 모듈로 프린트 시도.', 1);
case CUSTOMER_TYPE of
CUSTOMER_DEMO,
CUSTOMER_WELFND,
CUSTOMER_WELFNI,
CUSTOMER_SHCI,
CUSTOMER_SHSC,
CUSTOMER_WINSTN,
CUSTOMER_SKEC,
CUSTOMER_SANKYO,
CUSTOMER_KORENTAL :
begin
sImgPath := GetRunExePathDir + DIR_CONF + 'CI.bmp';
if FileExists(sImgPath) and not FileExists('C:\ProgramData\HE\CI.bmp') then
CopyFile(PChar(sImgPath), 'C:\ProgramData\HE\CI.bmp', false);
end;
end;
{$IFDEF PRT_STOP}
bIsWatchPtr := (ThdPrinter_ <> nil) and ThdPrinter_.IsWatch;
if bIsWatchPtr then
ThdPrinter_.StopWatch;
{$ENDIF}
sTopText := GetRunExePathDir + '$KvCttSchOpt.dat';
try
var O: ISuperObject := SO;
O.I['CSTT'] := Integer(csttPrint);
O.O['POpt'] := TTgJson.ValueToJsonObject<TPrtWaterEnt>(WInfo);
O.S['EN'] := sEmpNo_;
O.S['UN'] := sUName_;
O.S['DEPT'] := sDeptName_;
O.S['IP'] := NicService.GetIP;
O.I['CT'] := CUSTOMER_TYPE;
O.I['PrtDPI'] := PrefModel_.PrtDPI;
O.B['WM'] := WInfo.bUseWM;
if PO.PrtWaterCfg.bActive then
O.O['WMCfg'] := TTgJson.ValueToJsonObject<TPrtWaterCfg>(PO.PrtWaterCfg);
O.B['S2P'] := IsAdvancePrtProg;
O.B['ST'] := IsUseSnaptag and MaskPrtST;
O.D['STV'] := fST;
O.S['DPW'] := GetPrtWaterText(sPrtDocId);
O.S['PRTID'] := sPrtDocId;
O.I['RcvWnd'] := hRcvHwnd_;
if PrefModel_.PrtPopupNo then
O.B['NoPrtPopup'] := true;
if IsUsePrintMask then
begin
O.S['MskStr'] := sPrtMaskingStr_;
O.B['IsMask'] := true;
end;
// {$IFDEF DEBUG}
// // PDF로 강제 출력 추가 25_0602 14:36:14 kku
// O.S['FPDF'] := Format('C:\ProgramData\HE\%s.pdf', [FormatDateTime('yymmddhhnnss', Now)]);
// {$ENDIF}
if CUSTOMER_TYPE = CUSTOMER_GEC then
O.S['LB'] := sRecentLabel_;
var nRunCnt: Integer := 0;
if SaveJsonObjToFile(O, sTopText) then
begin
Inc(nRunCnt);
bIgrPrtPause_ := true;
{$IFDEF DEBUG}
ExecuteAppWaitUntilTerminate(sKvCsPath, Format('-p "%s"', [sTopText]), SW_SHOWNORMAL, 600000);
_Trace('외부 모듈로 프린트 시도... 종료', 1);
{$ELSE}
_Trace(Format('[MGKIM] kvcs run : %s, %s',[sKvCsPath, sTopText]));
var ProcInfo: TProcessInformation := ExecuteAppAsUser('explorer.exe', sKvCsPath, Format('-p "%s"', [sTopText]), SW_SHOWNORMAL);
if ProcInfo.dwProcessId <> 0 then
begin
_Trace('외부 모듈로 프린트 시도...성공', 1);
var dwExecuteTick: DWORD := GetTickCount;
while true do
begin
var dwWaitResult: DWORD := WaitForSingleObject(ProcInfo.hProcess, 50);
if dwWaitResult <> WAIT_TIMEOUT then
break;
// 메세지 없이 계속 돌아가는 상황을 위해서 빠져나오는 타임아웃을 추가함 (tcptunnel.exe 관련을 위해 추가)
if (GetTickCount - dwExecuteTick) > 600000 then
begin
TerminateProcess(ProcInfo.hProcess, 999);
exit;
end;
end;
_Trace('외부 모듈로 프린트 시도...성공 후 종료', 1);
end else
_Trace('외부 모듈로 프린트 시도...실패', 1);
{$ENDIF}
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 3, 0);
bIgrPrtPause_ := false;
if bIsNewApi_ then
begin
if OLog <> nil then
begin
if sOutCode <> '' then
begin
OLog.S['KEY_SUMMARY'] := 'ST=' + sOutCode + ', ' + OLog.S['KEY_SUMMARY'];
ThdEvent_.Push(OLog.AsJSon);
end else
ThdEvent_.Push(WInfo.LogJson);
end;
end else begin
SendEventLog(URI_USER_ACTION, LOGCODE_EVENT_PRINTER,
Format('Printer : %s, Document : %s', [WInfo.sPtrName, WInfo.sDocName]), false);
end;
var bPopup: Boolean := PO.Print.bPopup;
if IsDivPopup then
bPopup := PO.PrtAllowPopup;
if bPopup then
begin
if WInfo.bUseWM and PrefModel_.PrtWaterPop then
PopupMessage(TYPE_MSG_EVENT_PRINTWATER, WInfo.sPtrName + '|' + WInfo.sDocName)
else if IsDivPopup or (PO.Print.PrintKind = pkLog) then
PopupMessage(TYPE_MSG_PREVENT_PRINTER, WInfo.sPtrName + '|' + WInfo.sDocName);
end;
end;
if WInfo.sPostApvId <> '' then
MgPrint_.DelPrintInfo(WInfo.sPostApvId, true);
finally
DeleteDir(ExtractFilePath(WInfo.sImgPath));
///mgkim
// if FileExists(sTopText) then
// DeleteFile(PChar(sTopText));
{$IFDEF PRT_STOP}
if bIsWatchPtr and (ThdPrinter_ <> nil) then
ThdPrinter_.StartWatch;
{$ENDIF}
// 작업이 오래걸리면... 시간 처리에 문제가 생긴다 23_0912 18:23:39 kku
dtLastChk_ := Now;
end;
exit;
end;
end;
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 2, 0);
LB_DoPrintHere :
_Trace('PrtPDF Path = %s', [WInfo.sPdfPath], 3);
SendMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 2, WInfo.dwTotalPage);
{$IFDEF PRT_STOP}
bIsWatchPtr := (ThdPrinter_ <> nil) and ThdPrinter_.IsWatch;
if bIsWatchPtr then
ThdPrinter_.StopWatch;
{$ENDIF}
png := nil;
mf := nil;
try
Guard(ImgList, TStringList.Create);
case ProcType of
ptPdf : ;
ptPng :
begin
ExtrPrintImgFiles(WInfo.sImgPath, ImgList);
if ImgList.Count = 0 then
exit;
png := TPngImage.Create;
sImgPath := ImgList[0];
png.LoadFromFile(sImgPath);
end;
ptEmf :
begin
sImgDir := ExtractFilePath(WInfo.sImgPath);
ExtrFilesFromDir(sImgDir, ImgList, false, 'em1');
if ImgList.Count = 0 then
exit;
mf := TMetafile.Create;
sImgPath := ImgList[0];
mf.LoadFromFile(sImgPath);
end;
end;
sTopText := ''; //Trim(edTopText.Text);
sBottomText := GetPrtWaterText(sPrtDocId);
ZeroMemory(@bf, SizeOf(bf));
bf.AlphaFormat := 0; // 일반 비트맵 0, 32비트 비트맵 AC_SRC_ALPHA
bf.BlendFlags := 0; // 무조건 0
bf.BlendOp := AC_SRC_OVER; // AC_SRC_OVER
bf.SourceConstantAlpha := 125; // 투명도(투명 0 - 불투명 255)
bProcGrayW := false;
// Guard(ImgEn, TImageEn.Create(nil));
// Guard(F, TFont.Create);
// F.Size := 200; // 400
// F.Color := clSilver; // $F1F1F1; // clSilver; // clGray;
// F.Style := png.Canvas.Font.Style + [fsBold];
// Guard(bmp, TBitmap.Create);
{$IF false}
if (WInfo.sPdfPath <> '') and not bIsOutPdf then
begin
Guard(pdf, SynPdf.TPdfDocumentGDI.Create);
// pdf.UseUniscribe := true;
// pdf.StandardFontsReplace := true;
// pdf.UseFontFallBack := false;
// pdf.FontFallBackName := 'Tahoma';
pdf.ScreenLogPixels := 300; // 600;
case OrgDevMode.dmPaperSize of
DMPAPER_LETTERSMALL :
begin
pdf.DefaultPaperSize := psUserDefined;
pdf.DefaultPageWidth := 216 * 72;
pdf.DefaultPageHeight := 280 * 72;
end;
DMPAPER_LETTER : pdf.DefaultPaperSize := psLetter;
DMPAPER_LEGAL : pdf.DefaultPaperSize := psLegal;
DMPAPER_A3 : pdf.DefaultPaperSize := psA3;
DMPAPER_A4 : pdf.DefaultPaperSize := psA4;
DMPAPER_A4SMALL :
begin
pdf.DefaultPaperSize := psUserDefined;
pdf.DefaultPageWidth := 210 * 72;
pdf.DefaultPageHeight := 297 * 72;
end;
DMPAPER_A5 : pdf.DefaultPaperSize := psA5;
DMPAPER_B4 :
begin
pdf.DefaultPaperSize := psUserDefined;
pdf.DefaultPageWidth := 250 * 72;
pdf.DefaultPageHeight := 354 * 72;
end;
DMPAPER_B5 :
begin
pdf.DefaultPaperSize := psUserDefined;
pdf.DefaultPageWidth := 182 * 72;
pdf.DefaultPageHeight := 257 * 72;
end;
end;
if not bIsOutPdf then
begin
if png.Width > png.Height then
begin
var nSizeTemp: Integer := pdf.DefaultPageHeight;
pdf.DefaultPageHeight := pdf.DefaultPageWidth;
pdf.DefaultPageWidth := nSizeTemp;
end;
end;
pdfPage := pdf.AddPage;
pdf.VCLCanvas.Brush.Style := bsClear;
pdf.VCLCanvas.Font.Name := 'Tahoma';
nW := pdf.VCLCanvasSize.Width;
nH := pdf.VCLCanvasSize.Height;
if bIsOutPdf then
begin
end else begin
for i := 0 to ImgList.Count - 1 do
begin
try
if i <> 0 then
begin
try
if png <> nil then
FreeAndNil(png);
// i = 0은 위에서 미리 불러옴
png := TPngImage.Create;
sImgPath := ImgList[i];
png.LoadFromFile(sImgPath);
except
break;
end;
pdfPage := pdf.AddPage;
end;
// bmp.Assign(png);
// bmp.SaveToFile('C:\Users\kku\Desktop\0.bmp');
// png.SaveToFile('C:\Users\kku\Desktop\0.png');
PostMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 3, i + 1);
if not ProcessWatermark(pdf.VCLCanvas.Handle, sImgPath) then
begin
// png.SaveToFile('C:\Users\kku\Desktop\이전 바탕화면\출력 추출 데이터\test.png');
// pdf.VCLCanvas.StretchDraw(pngRect, png);
// pdf.VCLCanvas.StretchDraw() - 이게 어느날 갑자기 안되기 시작했다;;; 24_0930 15:30:53 kku
StretchBlt(pdf.VCLCanvas.Handle, 0, 0, nW, nH,
png.Canvas.Handle, 0, 0, png.Width, png.Height, SRCCOPY);
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. PrintPDF .. 1');
end;
end;
end;
try
pdf.SaveToFile(WInfo.sPdfPath);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. PrintPDF .. 2');
end;
end else
{$IFEND}
begin
pi := -1;
for i := 0 to Printer.Printers.Count - 1 do
begin
if Printer.Printers[i] = WInfo.sPtrName then
pi := i;
end;
if pi = -1 then
begin
TTgTrace.T('프린터 찾기 실패 .. Name=%s', [WInfo.sPtrName]);
exit;
end;
Printer.PrinterIndex := pi;
if not WInfo.bUseWM then
Printer.Title := WInfo.sDocName + ' *BSOne-'
else
Printer.Title := WInfo.sDocName + ' *BSOne';
hDev := 0;
Printer.GetPrinter(arrDevice, arrDriver, arrPort, hDev);
if hDev = 0 then
exit;
// for Test
// OrgDevMode.dmCopies := 2;
// OrgDevMode.dmCollate := 1;
var nCopies: Integer := OrgDevMode.dmCopies;
var nCopies0: Integer;
var dmCollate: DWORD := OrgDevMode.dmCollate;
DevMode := GlobalLock(hDev);
try
// OrgDevMode.dmCopies
// OrgDevMode.dmCollate : 0 이면 11 22 33 이렇게 출력, 1 이면 123 123 이렇게 출력
// 항상 1부로 나오도록 조정, 설정된 출력은 별도 처리 25_0604 13:01:05 kku
OrgDevMode.dmCopies := 1;
if ProcType <> ptPdf then
begin
if WInfo.bPaperV then
OrgDevMode.dmOrientation := DMORIENT_PORTRAIT
else
OrgDevMode.dmOrientation := DMORIENT_LANDSCAPE;
end;
// DevMode.dmPaperSize := WInfo.dwPageSizeT;
DevMode^ := OrgDevMode;
// DevMode.dmColor := DMCOLOR_COLOR; // DMCOLOR_MONOCHROME
// DevMode.dmColor := DMCOLOR_MONOCHROME; // DMCOLOR_MONOCHROME
Printer.SetPrinter(arrDevice, arrDriver, arrPort, hDev);
finally
GlobalUnlock(hDev);
end;
// 용지 가로, 세로 돌릴려면 Printer.BeginDoc 전에 해야한다..
// 일부 프로그램에서 오류남 23_0623 08:45:27 kku
// try
// if not bIsOutPdf then
// begin
// if not WInfo.bPaperV then
// Printer.Orientation := poLandscape
// else
// Printer.Orientation := poPortrait;
// end;
// except
// on E: Exception do
// ETgException.TraceException(Self, E, 'Fail .. Set Printer.Orientation');
// end;
// Guard(bmpW, Vcl.Graphics.TBitmap.Create);
// if pngW.Width > 0 then
// begin
// bmpW.Assign(pngW);
//// bmpW.Transparent := true;
//// bmpW.TransparentMode := tmFixed;
//// bmpW.TransparentColor := clWhite;
// end;
if (WInfo.dwTotalPage > 0) and (WInfo.dwTotalPage < ImgList.Count) then
begin
nCopies := ImgList.Count div WInfo.dwTotalPage;
dmCollate := 1; // 한 부씩 인쇄로 고정...
// TTgTrace.T('ProcessPrint() .. 2, SetCopies..%d', [nCopies]);
// 총 출력 부스만큼 이미지가 추출된 경우 처리... 25_0604 19:15:34 kku
for i := ImgList.Count - 1 downto 0 do
begin
if (i mod nCopies) > 0 then
ImgList.Delete(i);
end;
end;
nW := 0;
nH := 0;
Printer.BeginDoc;
try
if not Printer.Printing or Printer.Aborted then
begin
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRINTWATER_PROGRESS, 0, 0);
exit;
end;
LB_Collate1 :
case ProcType of
ptPdf :
begin
TTgTrace.T('ProcessPrint() ... 7');
var doc: EM.PdfiumCore.TPdfDocument;
Guard(doc, EM.PdfiumCore.TPdfDocument.Create);
doc.LoadFromFile(WInfo.sImgPath);
nW := GetDeviceCaps(Printer.Canvas.Handle, HORZRES);
nH := GetDeviceCaps(Printer.Canvas.Handle, VERTRES);
var page: EM.PdfiumCore.TPdfPage;
var bIsPageLoad, bPagePortraitOrientation: Boolean;
var nPageW, nPageH: Integer;
bPagePortraitOrientation := nW > nH;
TTgTrace.T('ProcessPrint() ... 8');
// FPU 예외 마스킹 (부동소수점 예외를 무시하게 함) >> PDFium 버그... 25_0612 16:12:04 kku
// 현재 FPU 컨트롤 워드 저장
var SavedCW: WORD := Get8087CW;
try
// 모든 FPU 예외 마스크
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
// var bmp: TBitmap := nil;
// Guard(bmp, TBitmap.Create);
// bmp.PixelFormat := pf32bit;
// bmp.Canvas.Brush.Color := clWhite;
// bmp.SetSize(nW, nH);
for i := 0 to doc.PageCount - 1 do
begin
if not Printer.Printing or Printer.Aborted then
break;
nPageW := nW;
nPageH := nH;
if i <> 0 then
Printer.NewPage;
// bIsPageLoad := doc.IsPageLoaded(i);
try
page := doc.Pages[i];
// if bPagePortraitOrientation <> (Trunc(page.Width) > Trunc(page.Height)) then
// begin
// var nTmp: Integer := nPageW;
// nPageW := nPageH;
// nPageH := nTmp;
// end;
TTgTrace.T('ProcessPrint() ... 9 - %d', [i]);
nCopies0 := nCopies;
PostMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 3, i + 1);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 0, i + 1);
LB_CollatePdf :
// page.Draw(Printer.Handle, 0, 0, nPageW, nPageH, prNormal, [proPrinting, proNoNativeText, proNoCatch]);
if bPagePortraitOrientation <> (Trunc(page.Width) > Trunc(page.Height)) then
page.Draw(Printer.Handle, 0, 0, nPageW, nPageH, pr90Clockwise, [proPrinting, proNoCatch])
else
page.Draw(Printer.Handle, 0, 0, nPageW, nPageH, prNormal, [proPrinting, proNoCatch]);
// if bmp <> nil then
// begin
// if bPagePortraitOrientation <> (Trunc(page.Width) > Trunc(page.Height)) then
// page.Draw(bmp.Canvas.Handle, 0, 0, nPageW, nPageH, pr90Clockwise, [proPrinting, proNoCatch])
// else
// page.Draw(bmp.Canvas.Handle, 0, 0, nPageW, nPageH, prNormal, [proPrinting, proNoCatch]);
// bmp.SaveToFile(Format('C:\test\%d.bmp', [i]));
// bmp.Canvas.FillRect(Rect(0, 0, bmp.Width, bmp.Height));
// end;
Dec(nCopies0);
if (dmCollate = 0) and (nCopies0 > 0) then
begin
Printer.NewPage;
goto LB_CollatePdf
end;
finally
// if not bIsPageLoad and (page <> nil) then
// page.Close;
end;
end;
finally
// 원래 상태 복원
Set8087CW(SavedCW);
end;
Dec(nCopies);
if (dmCollate <> 0) and (nCopies > 0) then
begin
Printer.NewPage;
goto LB_Collate1;
end;
TTgTrace.T('ProcessPrint() ... 10');
end;
ptPng :
begin
for i := 0 to ImgList.Count - 1 do
begin
if not Printer.Printing or Printer.Aborted then
break;
try
if i <> 0 then
begin
try
if png <> nil then
FreeAndNil(png);
// i = 0은 위에서 미리 불러옴
png := TPngImage.Create;
sImgPath := ImgList[i];
png.LoadFromFile(sImgPath);
except
{$IFDEF DEBUG} ASSERT(false); {$ENDIF}
break;
end;
Printer.NewPage;
end;
nW := GetDeviceCaps(Printer.Canvas.Handle, HORZRES);
nH := GetDeviceCaps(Printer.Canvas.Handle, VERTRES);
nCopies0 := nCopies;
PostMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 3, i + 1);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 0, i + 1);
LB_CollatePng :
// if not ProcessWatermark(Printer.Canvas.Handle, sImgPath) then
if (ProcType <> ptPng) or
not ProcessWatermarkToImage(png, Printer.Canvas.Handle,
nW, nH, WInfo, fST, sTopText, sBottomText, bmpWaterP, sImgPath) then
begin
// png.SaveToFile(Format('c:\test\test-%d.png', [i + 1]));
StretchBlt(Printer.Canvas.Handle, 0, 0, nW, nH,
png.Canvas.Handle, 0, 0, png.Width, png.Height, SRCCOPY);
end;
Dec(nCopies0);
if (dmCollate = 0) and (nCopies0 > 0) then
begin
Printer.NewPage;
goto LB_CollatePng;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoPrint ..');
end;
end;
Dec(nCopies);
if (dmCollate <> 0) and (nCopies > 0) then
begin
if png <> nil then
FreeAndNil(png);
png := TPngImage.Create;
sImgPath := ImgList[0];
png.LoadFromFile(sImgPath);
Printer.NewPage;
goto LB_Collate1;
end;
end;
ptEmf :
begin
for i := 0 to ImgList.Count - 1 do
begin
if not Printer.Printing or Printer.Aborted then
break;
try
if i <> 0 then
begin
try
if mf <> nil then
FreeAndNil(mf);
// i = 0은 위에서 미리 불러옴
mf := TMetafile.Create;
sImgPath := ImgList[i];
mf.LoadFromFile(sImgPath);
if (mf.MMWidth = 0) or (mf.MMHeight = 0) then
continue;
except
{$IFDEF DEBUG} ASSERT(false); {$ENDIF}
break;
end;
Printer.NewPage;
end;
nW := GetDeviceCaps(Printer.Canvas.Handle, HORZRES);
nH := GetDeviceCaps(Printer.Canvas.Handle, VERTRES);
nCopies0 := nCopies;
PostMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 3, i + 1);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 0, i + 1);
LB_CollateEmf :
Printer.Canvas.StretchDraw(Rect(0, 0, nW, nH), mf);
Dec(nCopies0);
if (dmCollate = 0) and (nCopies0 > 0) then
begin
Printer.NewPage;
goto LB_CollateEmf;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoPrint ..');
end;
end;
Dec(nCopies);
if (dmCollate <> 0) and (nCopies > 0) then
begin
if mf <> nil then
FreeAndNil(mf);
mf := TMetafile.Create;
sImgPath := ImgList[0];
mf.LoadFromFile(sImgPath);
Printer.NewPage;
goto LB_Collate1;
end;
end;
end;
finally
if Printer.Printing then
Printer.EndDoc;
end;
end;
if bIsNewApi_ then
begin
if OLog <> nil then
begin
if sOutCode <> '' then
begin
OLog.S['KEY_SUMMARY'] := 'ST=' + sOutCode + ', ' + OLog.S['KEY_SUMMARY'];
ThdEvent_.Push(OLog.AsJSon);
end else
ThdEvent_.Push(WInfo.LogJson);
end;
end else begin
SendEventLog(URI_USER_ACTION, LOGCODE_EVENT_PRINTER,
Format('Printer : %s, Document : %s', [WInfo.sPtrName, WInfo.sDocName]), false);
end;
var bPopup: Boolean := PO.Print.bPopup;
if IsDivPopup then
bPopup := PO.PrtAllowPopup;
if bPopup then
begin
if WInfo.bUseWM and PrefModel_.PrtWaterPop then
PopupMessage(TYPE_MSG_EVENT_PRINTWATER, WInfo.sPtrName + '|' + WInfo.sDocName)
else if IsDivPopup or (PO.Print.PrintKind = pkLog) then
PopupMessage(TYPE_MSG_PREVENT_PRINTER, WInfo.sPtrName + '|' + WInfo.sDocName);
end;
finally
if png <> nil then
FreeAndNil(png);
if mf <> nil then
FreeAndNil(mf);
if bmpWaterP <> nil then
FreeAndNil(bmpWaterP);
DeleteDir(ExtractFilePath(WInfo.sImgPath));
SendMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 0, 0);
SendMessage(gMgSvc.RcvHwnd, WM_POPUP_PRTW_PROGRESS, 3, 0);
{$IFDEF PRT_STOP}
if bIsWatchPtr and (ThdPrinter_ <> nil) then
ThdPrinter_.StartWatch;
{$ENDIF}
// 작업이 오래걸리면... 시간 처리에 문제가 생긴다 23_0912 18:23:39 kku
dtLastChk_ := Now;
end;
except
on E: Exception do
begin
ETgException.TraceException(Self, E, 'Fail .. ProcessPrintWaterEnt()');
SendMessage(hRcvHwnd_, WM_POPUP_PRINTWATER_PROGRESS, 0, 0);
{$IFDEF PRT_STOP}
if bIsWatchPtr and (ThdPrinter_ <> nil) then
ThdPrinter_.StartWatch;
{$ENDIF}
end;
end;
end;
procedure TManagerService.ResetPersonalScan;
begin
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cppn');
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cptd');
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cpid');
DeleteDir(GetRunExePathDir + DIR_CTTSCHRST);
if not IsNewApi then
SetSchRstVul(false);
MgCttSch_.Clear;
bClearCampn_ := true;
end;
procedure TManagerService.RetryPersonalScan;
begin
bIgrLastWorkCampn_ := true;
end;
//function TManagerService.IsHecDev: Boolean; // HEC 개발계인가?
//begin
// Result := IsHD and (Pos('10.10.144.113:8443', gMgSvc.DestIPort) = 0);
//end;
function TManagerService.GetAipPath: String;
var
sAipExe: String;
begin
Result := '';
if PrefModel_.AipOff then
exit;
if not IsSupportAIP then
exit;
if bWin7Ver_ then
exit;
sAipExe := EXE_AIP;
{$IFDEF DEBUG}
case CUSTOMER_TYPE of
CUSTOMER_DEV : sAipExe := 'dev_BSOne-AIP-Decrypt.exe';
CUSTOMER_UNITUS : sAipExe := 'unitus_BSOne-AIP-Decrypt.exe';
end;
{$ENDIF}
//{$IFNDEF DEBUG}
Result := GetRunExePathDir + DIR_AIP17 + sAipExe;
if not FileExists(Result) then
//{$ENDIF}
Result := GetRunExePathDir + DIR_AIP14 + sAipExe;
if not FileExists(Result) then
Result := GetRunExePathDir + DIR_AIP12 + sAipExe;
end;
function TManagerService.GetUrlBlockList: String;
var
PO: TPrefModel;
begin
Result := '';
try
PO := GetModePolicy;
if PrefModel_.UrlBlkRuleList <> '' then
begin
if PO.WebbMonKind = wmkIncBlock then
Result := PO.UrlBlockList + '|' + PrefModel_.UrlBlkRuleList;
end;
if Result = '' then
Result := PO.UrlBlockList;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetUrlBlockList()');
end;
end;
procedure TManagerService.AddEncIgr(sPath: String);
begin
if ThdReact_ <> nil then
ThdReact_.AddEncIgr(sPath);
end;
procedure TManagerService.AddAfterEnc(sPath: String);
begin
if ThdReact_ <> nil then
ThdReact_.AddAfterEnc(sPath);
end;
function TManagerService.HasEncIgr(sPath: String; bChkDel: Boolean = false): Boolean;
begin
if ThdReact_ <> nil then
Result := ThdReact_.HasEncIgr(sPath, bChkDel);
end;
function TManagerService.GetModeKind: TBS1ModeKind;
begin
Lock;
try
Result := BS1ModeKind_;
finally
Unlock;
end;
end;
procedure TManagerService.SetModeKind(aKind: TBS1ModeKind);
begin
Lock;
try
if BS1ModeKind_ <> aKind then
BS1ModeKind_ := aKind;
finally
Unlock;
end;
end;
procedure TManagerService.SetModeName(sModeName: String);
begin
Lock;
try
if sModeName_ <> sModeName then
sModeName_ := sModeName;
finally
Unlock;
end;
end;
function TManagerService.GetModeName: String;
begin
Lock;
try
Result := sModeName_;
finally
Unlock;
end;
end;
function TManagerService.AddOpenDoc(dwPid: DWORD; sPath: String): Boolean;
begin
Result := false;
if DcOpenDoc_ = nil then
exit;
Lock;
try
if not DcOpenDoc_.ContainsKey(dwPid) then
begin
DcOpenDoc_.Add(dwPid, sPath);
Result := true;
end else begin
Result := not SameText(DcOpenDoc_[dwPid], sPath);
if Result then
DcOpenDoc_[dwPid] := sPath;
end;
finally
Unlock;
end;
end;
procedure TManagerService.DelOpenDocProc(dwPid: DWORD);
begin
if DcOpenDoc_ = nil then
exit;
Lock;
try
if DcOpenDoc_.ContainsKey(dwPid) then
DcOpenDoc_.Remove(dwPid);
finally
Unlock;
end;
end;
procedure TManagerService.CheckEmpNo_TMAP;
var
sTemp,
sAccount: String;
begin
if CUSTOMER_TYPE <> CUSTOMER_TMAP then
exit;
try
sAccount := WTS_GetCurrentUserName;
if (sAccount <> '') and (sAccount_ <> sAccount) then
begin
_Trace('[07] 사번 변경, %s > %s', [AgentModel_.EmpNo, sAccount], 1);
SendEventLogEx(LOG_CHANGE_EMPNO, Format('[Fixed] EmpId Changed. (%s > %s)', [AgentModel_.EmpNo, sAccount]), false);
sAccount_ := sAccount;
AgentModel_.EmpNo := sAccount_;
AgentModel_.Save;
UpdateAgentInfo;
end;
if (sEmpNo_ <> '') and (sEmpNo_ <> 'Temp') then
begin
try
sTemp := sEmpNo_.ToUpper;
if (sTemp[1] <> 'T') and (sTemp[1] <> 'Y') then
begin
sTemp := 'Temp';
exit;
end;
Delete(sTemp, 1, 1);
if StrToIntDef(sTemp, 0) = 0 then
sTemp := 'Temp';
finally
if sTemp = 'Temp' then
begin
_Trace('[08] 사번 변경, %s > %s', [AgentModel_.EmpNo, sTemp], 1);
SendEventLogEx(LOG_CHANGE_EMPNO, Format('[Fixed] EmpId Changed. (%s > %s)', [AgentModel_.EmpNo, sTemp]), false);
AgentModel_.EmpNo := sTemp;
AgentModel_.Save;
UpdateAgentInfo;
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. CheckEmpNo_TMAP()');
end;
end;
procedure TManagerService.ProcessEndSession;
begin
_Trace('ProcessEndSession() ..');
if not bIsEndSession_ then
begin
_Trace('ProcessEndSession() .. 1');
bIsEndSession_ := true;
if ThdEvent_ <> nil then
ThdEvent_.IsEndSession := true;
if GetModePolicy.IsPcStatePower then
begin
if Connected then
gMgSvc.DirectSendEventLog('none', MONITOR_PC_POWER, 'Power Off', false)
else
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'EDT', IntToStr(DelphiToJavaDateTime(Now)), true);
end;
end;
end;
initialization
if _CheckVpnList = nil then _CheckVpnList := TStringList.Create;
Finalization
if _CheckVpnList <> nil then FreeAndNil(_CheckVpnList);
// if _bmpWaterP <> nil then FreeAndNil(_bmpWaterP);
end.