BSOne.SFC/eCrmHE/LIB_Common/CrmUtil.pas

415 lines
13 KiB
Plaintext

{*******************************************************}
{ }
{ CrmUtil }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit CrmUtil;
interface
uses
IdHTTP, System.Classes, Winapi.Windows;
function GetRandomString(nLen: Integer): String;
function GetADUserName: String;
function GetUserNameFromExplorer: String;
function VerifyEmpNo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): Boolean;
function GetEmpNoInfo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): String;
function GetQuarantineInfo(sSvrUrl: String; aHTTP: TIdHTTP; sHostInfo: String): String;
function ExtrTextFromImage(sImgPath: String; aAngle: Extended = 0): String;
function SendData(h: HWND; dwCmd: DWORD; const sData: String): LONGLONG;
// KBIZ에서 엑셀이 한번에 재대로 실행 안되는 현상이 있어서 작성
procedure ExcelCheckAndHideRun(sUserSid: String);
implementation
uses
Tocsg.Registry, System.SysUtils, Tocsg.Exception,
Tocsg.Process, Condition, Tocsg.Trace, Tocsg.WTS, Tocsg.Safe, Tocsg.Path,
GlobalDefine, Tocsg.WinInfo, IdMultipartFormData, superobject, Tocsg.Files,
Tocsg.Shell, Tocsg.Graphic, Winapi.Messages,
DefineHelper, Tocsg.Strings;
var
_DoGetInfoCount: Integer = 0;
function GetRandomString(nLen: Integer): String;
const
arrRanChar: array [0..13] of Char =
('a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'x', 't', 'z', 'u', 'l', 'k');
var
i: Integer;
begin
Result := '';
if nLen = 0 then
Randomize;
for i := 1 to nLen do
Result := Result + arrRanChar[Random(13)];
end;
function GetADUserName: String;
var
sAdHostName: String;
begin
Result := '';
// AD 환경에서 호스트명(컴퓨터 이름)을 다르게 가져오도록 보완 (김경덕프로 요청, 다이이찌산쿄) 22_0629 09:37:23 kku
// 주의 : 비밀번호 취약상태 점검때는 사용하면 안된다. 이렇게 하면 로그온정보 제대로 가져올 수 없음
sAdHostName := GetRegValueAsString(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\DataStore\Machine\0', 'szTargetName');
// 보완 24_0108 12:57:40 kku
if sAdHostName = '' then
sAdHostName := GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName', 'ComputerName');
if sAdHostName <> '' then
begin
var sUser: String := '';
var sRegKey: String := GetRegRecentUserSid;
if sRegKey <> '' then
begin
sUser := Trim(GetRegValueAsString(HKEY_USERS, sRegKey + '\Volatile Environment', 'USERNAME'));
if sUser = '' then
sUser := GetUserNameFromReg(sRegKey);
if sUser = '' then
TTgTrace.T('RecentUserSid = %s', [sRegKey]);
end else
TTgTrace.T('Fail .. GetADUserName()');
if sUser = '' then
begin
sUser := WTS_GetCurrentUserName; // 패스워드 취약점검 안하면 사용자 계정 상관없어서 이렇게 처리 22_0705 14:38:37 kku
if sUser = '' then
TTgTrace.T('Fail?? WTS_GetCurrentUserName()'); // AD 환경에서 실패하는것을 확인함. 다시 실행하면 되는 경우 있음 22_0721 15:43:52 kku
end;
Result := sAdHostName + '\' + sUser;
exit;
end;
end;
function GetUserNameFromExplorer: String;
var
PList: TProcessEntList;
pEnt: PProcessEntInfo;
PidList: TProcessIdList;
i: Integer;
begin
if IsUseLocalHostName then
begin
// 로컬 호스트네임으로 가져오도록 고정 24_0321 10:04:54 kku
var sCom: String := GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Control\ComputerName\ComputerName', 'ComputerName');
var sUser: String := GetRegValueAsString(HKEY_USERS, GetRegRecentUserSid + '\Volatile Environment', 'USERNAME');
// 카스퍼스키 계정 프록시? 기능 때문에 제대로 계정 정보를 가져올수 없다...
// GetUserNameFromReg() 로도 계정 권한이 "%SystemRoot%\ServiceProfiles\ksnproxy" 로 확인됨 24_0327 15:47:43 kku
if sUser = '' then
sUser := WTS_GetCurrentUserName;
if (sCom <> '') and (sUser <> '') then
begin
Result := sCom + '\' + sUser;
exit;
end;
end;
if IsUseActiveDirectory then // and IsSkipPwd then
begin
Result := GetADUserName;
if Result <> '' then
exit;
end;
Result := GetDomainUserNameFromReg;
if Result <> '' then
exit;
try
Guard(PidList, TProcessIdList.Create);
if GetProcessPidsByName('explorer.exe', PidList) > 0 then
begin
Guard(PList, TProcessEntList.Create);
PList.UpdateProcessList;
for i := 0 to PidList.Count - 1 do
begin
pEnt := PList.GetProcInfoByPid(PidList[i]);
if pEnt <> nil then
begin
Result := Trim(pEnt.sOwner);
if Result = '\\\' then
Result := '';
if Result <> '' then
begin
DeleteFile(PChar(GetRunExePathDir + LOG_RESTART));
exit;
end;
end;
end;
end;
if Result = '' then
begin
var sPath: String := GetRunExePathDir + LOG_RESTART;
if FileExists(sPath) then
begin
// 다시 시작했는데도 안되면.. 그냥 일반적으로 구해준다. 22_0613 08:16:07 kku
DeleteFile(PChar(sPath));
Result := GetComName + '\' + WTS_GetCurrentUserName;
TTgTrace.T('Fail .. GetUserNameFromExplorer(), Restart.. UserName="%s"', [Result]);
end else begin
Inc(_DoGetInfoCount);
TTgTrace.T('Fail .. GetUserNameFromExplorer(), TryCount=%d', [_DoGetInfoCount]);
if _DoGetInfoCount > 5 then
begin
var sName: String := GetUserNameFromReg;
if sName = '' then
begin
TTgTrace.T('Fail .. GetUserNameFromExplorer(), Terminate..');
WriteLnFileEndUTF8(sPath, Format('[%s] Fail .. GetUserNameFromExplorer()', [DateTimeToStr(Now)]));
TerminateProcess(GetCurrentProcess, 900);
end else
Result := GetComName + '\' + sName;
end;
end;
end;
except
on E: Exception do
begin
Result := GetComName + '\' + WTS_GetCurrentUserName;
ETgException.TraceException(E, 'Fail .. GetUserNameFromExplorer()');
end;
end;
end;
function VerifyEmpNo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): Boolean;
var
ss: TStringStream;
nOldTM1,
nOldTM2: Integer;
O: ISuperObject;
begin
Result := false;
try
if CUSTOMER_TYPE = CUSTOMER_CNSCERT then
begin
// CNSCERT는 인사연동을 하지 않기 때문에 사번 패턴만 검증함 22_0711 16:14:43 kku
Result := IsCheckEmpNoCNSCERT(sEmpNo);
exit;
end;
nOldTM1 := aHTTP.ReadTimeout;
nOldTM2 := aHTTP.ConnectTimeout;
try
// sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'agentEmpNoChecks.do', [rfReplaceAll]);
// sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'agentEmpNoCheck.do', [rfReplaceAll]);
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'agentEmpInfo.do', [rfReplaceAll]);
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'agentEmpInfos.do', [rfReplaceAll]);
Guard(ss, TStringStream.Create('{\"Request : HeartBeat\"}', TEncoding.UTF8));
aHTTP.Request.ContentType := 'application/json; charset=utf-8';
aHTTP.Request.CustomHeaders.Clear; // 메인에서 DRM 처리도 같이 해주고 있기 때문에 초기화 해줘야 한다 22_0602 08:25:35 kku
aHTTP.Request.CustomHeaders.Values['requestType'] := sEmpNo;
// Result := aHTTP.Post(sSvrUrl, ss) = 'true';
O := SO(aHTTP.Post(sSvrUrl, ss));
Result := O.S['result'] = 'true';
finally
aHTTP.ReadTimeout := nOldTM1;
aHTTP.ConnectTimeout := nOldTM2;
end;
except
{$IFDEF TRACE1}
on E: Exception do
ETgException.TraceException(Self, E, Format('Fail .. VerifyEmpNo(), RqType=%s', [sRqType]));
{$ENDIF}
end;
end;
function GetEmpNoInfo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): String;
var
ss: TStringStream;
nOldTM1,
nOldTM2: Integer;
begin
Result := '';
try
nOldTM1 := aHTTP.ReadTimeout;
nOldTM2 := aHTTP.ConnectTimeout;
try
if CUSTOMER_TYPE = CUSTOMER_CNSCERT then
begin
// CNSCERT는 인사연동을 하지 않기 때문에 사번 패턴만 검증함 22_0711 16:14:43 kku
if IsCheckEmpNoCNSCERT(sEmpNo) then
Result := 'true';
exit;
end;
if Pos('agentLogRequests.do', sSvrUrl) = 0 then
begin
sSvrUrl := sSvrUrl + 'agentEmpInfo.do';
end else begin
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'agentEmpInfo.do', [rfReplaceAll]);
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'agentEmpInfos.do', [rfReplaceAll]);
end;
Guard(ss, TStringStream.Create('{\"Request : HeartBeat\"}', TEncoding.UTF8));
aHTTP.Request.ContentType := 'application/json; charset=utf-8';
aHTTP.Request.CustomHeaders.Clear; // 메인에서 DRM 처리도 같이 해주고 있기 때문에 초기화 해줘야 한다 22_0602 08:25:35 kku
aHTTP.Request.CustomHeaders.Values['requestType'] := sEmpNo;
Result := aHTTP.Post(sSvrUrl, ss);
finally
aHTTP.ReadTimeout := nOldTM1;
aHTTP.ConnectTimeout := nOldTM2;
end;
except
// on E: Exception do
// raise Exception.Create(E.Message);
{$IFDEF TRACE1}
on E: Exception do
ETgException.TraceException(Self, E, Format('Fail .. GetEmpNoInfo(), RqType=%s', [sRqType]));
{$ENDIF}
end;
end;
function GetQuarantineInfo(sSvrUrl: String; aHTTP: TIdHTTP; sHostInfo: String): String;
var
ss: TStringStream;
nOldTM1,
nOldTM2: Integer;
begin
Result := '';
try
nOldTM1 := aHTTP.ReadTimeout;
nOldTM2 := aHTTP.ConnectTimeout;
try
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'getQuarantineFileInfo.do', [rfReplaceAll]);
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'getQuarantineFileInfo.do', [rfReplaceAll]);
Guard(ss, TStringStream.Create('{\"Request : HeartBeat\"}', TEncoding.UTF8));
// Guard(ss, TStringStream.Create(sEmpNo, TEncoding.UTF8));
aHTTP.Request.ContentType := 'application/json; charset=utf-8';
aHTTP.Request.CustomHeaders.Clear; // 메인에서 DRM 처리도 같이 해주고 있기 때문에 초기화 해줘야 한다 22_0602 08:25:35 kku
aHTTP.Request.CustomHeaders.Values['requestType'] := sHostInfo; // gMgSvc.AgentModel.AgentId;
Result := aHTTP.Post(sSvrUrl, ss);
finally
aHTTP.ReadTimeout := nOldTM1;
aHTTP.ConnectTimeout := nOldTM2;
end;
except
// on E: Exception do
// raise Exception.Create(E.Message);
{$IFDEF TRACE1}
on E: Exception do
ETgException.TraceException(Self, E, Format('Fail .. GetQuarantineInfo(), RqType=%s', [sRqType]));
{$ENDIF}
end;
end;
function ExtrTextFromImage(sImgPath: String; aAngle: Extended = 0): String;
var
sOcr,
sOutPath,
sTempPath: String;
StrList: TStringList;
begin
Result := '';
sTempPath := '';
sOcr := GetRunExePathDir + DIR_CONF + EXE_OCR;
if not FileExists(sOcr) then
sOcr := GetRunExePathDir + EXE_OCR;
if FileExists(sOcr) then
begin
sOutPath := sOcr[1] + ':\ProgramData\HE\Task\' + ExtractFileName(sImgPath) + '.$xt';
if ForceDirectories(ExtractFilePath(sOutPath)) then
begin
if aAngle <> 0 then
begin
sTempPath := CutFileExt(sImgPath) + 'R18.png';
if RotatePngFile(sImgPath, sTempPath, aAngle) then
sImgPath := sTempPath;
end;
try
ExecuteAppWaitUntilTerminate(sOcr, Format('"%s" "%s"', [sImgPath, sOutPath]), SW_HIDE);
finally
if sTempPath <> '' then
DeleteFile(sTempPath);
end;
if FileExists(sOutPath) then
begin
Result := ExtractTextSafe(sOutPath);
DeleteFile(sOutPath);
end;
end;
end;
end;
function SendData(h: HWND; dwCmd: DWORD; const sData: String): LONGLONG;
var
CopyData: TCopyDataStruct;
begin
CopyData.dwData := dwCmd;
CopyData.cbData := (Length(sData) + 1) * 2;
CopyData.lpData := PChar(sData);
Result := SendMessage(h, WM_COPYDATA, 0, NativeInt(@CopyData));
end;
procedure ExcelCheckAndHideRun(sUserSid: String);
var
sPath: String;
begin
if GetProcessPidByName('excel.exe') <> 0 then
exit;
sPath := '';//GetRegValueAsString(HKEY_USERS, sUserSid + '\Software\Microsoft\Windows\CurrentVersion\Extensions', 'xlsx');
if (sPath = '') or not FileExists(sPath) then
begin
sPath := GetRegValueAsString(HKEY_CLASSES_ROOT, 'dqyfile\DefaultIcon', '');
if sPath <> '' then
begin
var nPos: Integer := Pos(',', sPath);
if nPos > 0 then
Delete(sPath, nPos, Length(sPath) - nPos + 1);
if not FileExists(sPath) then
exit;
end;
end;
{$IFDEF DEBUG}
ExecutePath_hide(sPath);
{$ELSE}
var O: ISuperObject := SO;
O.I['Cmd'] := HPCMD_EXECUTE_FILE;
O.S['Path'] := sPath;
O.B['Hide'] := true;
SaveJsonObjToFile(O, GetRunExePathDir + DIR_CONF + DAT_PARAM);
var sHlpExe: String := GetRunExePathDir + DIR_CONF + EXE_HLP;
ExecuteAppAsUser('explorer.exe', sHlpExe, '', SW_HIDE);
{$ENDIF}
end;
end.