BSOne.SFC/eCrmHE/EXE_eCrmHomeEdition/Handle/HandleSecurity.pas

424 lines
11 KiB
Plaintext

{*******************************************************}
{ }
{ HandleSecurity }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit HandleSecurity;
interface
uses
Tocsg.Obj, System.SysUtils, System.Classes, SecureApp, Tocsg.WscApi,
NetFwTypeLib_TLB;
const
TYPE_AV = 'AntiVirus';
TYPE_FIREWALL = 'Firewall';
TYPE_AS = 'AndtiSpyware';
// IGRNORE_AV = 'FortiClient';
type
THandleSecurity = class(TTgObject)
private
sWinVer_: String;
fwPolicy2_: INetFwPolicy2;
AvList_,
FwList_,
AsList_: TSecureAppList;
// IgrAvList_: TStringList;
procedure UpdateAv(aList: TWSCProductEntList);
procedure UpdateFw(aList: TWSCProductEntList);
procedure UpdateAs(aList: TWSCProductEntList);
public
Constructor Create(sWinVer: String);
Destructor Destroy; override;
procedure Update(aList: TWSCProductEntList);
function GetMainAv: TSecureApp;
function GetMainFw: TSecureApp;
function GetMainAs: TSecureApp;
function HasV3: Boolean;
property AvList: TSecureAppList read AvList_;
property FwList: TSecureAppList read FwList_;
property AsList: TSecureAppList read AsList_;
end;
implementation
uses
Tocsg.Safe, Condition, Tocsg.Strings, Tocsg.Convert, Tocsg.Exception, Tocsg.Firewall;
{ THandleSecurity }
Constructor THandleSecurity.Create(sWinVer: String);
var
sIgrAv: String;
begin
Inherited Create;
sWinVer_ := sWinVer;
fwPolicy2_ := nil;
// sIgrAv := IGRNORE_AV;
// if IsIgnoreWinDependerAv then
// SumString(sIgrAv, 'Defender', '|');
// IgrAvList_ := TStringList.Create;
// SplitString(UpperCase(sIgrAv), '|', IgrAvList_);
AvList_ := TSecureAppList.Create;
FwList_ := TSecureAppList.Create;
AsList_ := TSecureAppList.Create;
AvList_.Add(TSecureApp.Create('Windows Defender', TYPE_AV, 'up-to-date', '', '', true));
FwList_.Add(TSecureApp.Create('Windows Firewall', TYPE_FIREWALL, 'up-to-date', '', '', true));
end;
Destructor THandleSecurity.Destroy;
begin
FreeAndNil(AsList_);
FreeAndNil(FwList_);
FreeAndNil(AvList_);
// FreeAndNil(IgrAvList_);
Inherited;
end;
procedure THandleSecurity.Update(aList: TWSCProductEntList);
begin
if aList.Count = 0 then
exit;
case aList.Provider of
WSC_SECURITY_PROVIDER_FIREWALL : UpdateFw(aList);
WSC_SECURITY_PROVIDER_ANTIVIRUS : UpdateAv(aList);
WSC_SECURITY_PROVIDER_ANTISPYWARE : UpdateAs(aList);
end;
end;
procedure THandleSecurity.UpdateAv(aList: TWSCProductEntList);
var
sName,
sStatus,
sPath,
sTime,
sTemp: String;
bState: Boolean;
i, c: Integer;
app: TSecureApp;
begin
sName := '';
sStatus := 'Out-Of-Date';
sPath := '';
sTime := '';
bState := false;
try
for i := 0 to aList.Count - 1 do
begin
sName := aList[i].sName;
// FortiClient VPN이 잡히는 경우가 있다고 한다 25_0312 14:33:05 kku
if (sName <> '') and sName.ToUpper.Contains('FORTICLIENT') then
continue;
bState := aList[i].nState = WSC_SECURITY_PRODUCT_STATE_ON;
sStatus := BooleanToStr(aList[i].nStatus = WSC_SECURITY_PRODUCT_UP_TO_DATE,
'up-to-date', 'out-of-date');
sTime := aList[i].sStateTimestamp;
if sName <> '' then
begin
if CUSTOMER_TYPE = CUSTOMER_METLIFE then
begin
// 메트라이프는 "CrowdStrike Falcon Sensor" 백신만 인식되도록 함 23_0213 16:17:34 kku
app := TSecureApp.Create(sName, TYPE_AV, sStatus, sPath, sTime, bState);
case AvList_.Count of
0 : ;
1 : if AvList_[0].Name.Contains('Defender') then AvList_.Clear;
else begin
for c := AvList_.Count - 1 downto 0 do
begin
if AvList_[c].Name = app.Name then
AvList_.Delete(c);
end;
end;
end;
if app.Name.Contains('CrowdStrike') then
AvList_.Add(app)
else
app.Free;
end else
if IsIgnoreWinDependerAv then
begin
app := TSecureApp.Create(sName, TYPE_AV, sStatus, sPath, sTime, bState);
case AvList_.Count of
0 : ;
1 : if AvList_[0].Name.Contains('Defender') then AvList_.Clear;
else begin
for c := AvList_.Count - 1 downto 0 do
begin
if (AvList_[c].Name = app.Name) or
(AvList_[c].Name.Contains('Defender') and app.Name.Contains('Defender')) then
AvList_.Delete(c);
end;
end;
end;
if not app.Name.Contains('Defender') then
AvList_.Add(app)
else
app.Free;
end else begin
app := TSecureApp.Create(sName, TYPE_AV, sStatus, sPath, sTime, bState);
for c := 0 to AvList_.Count - 1 do
if (AvList_[c].Name = app.Name) or
(AvList_[c].Name.Contains('Defender') and app.Name.Contains('Defender')) then
begin
AvList_.Delete(c);
break;
end;
AvList_.Add(app);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateAv()');
end;
end;
procedure THandleSecurity.UpdateFw(aList: TWSCProductEntList);
var
sName,
sStatus,
sPath,
sTime,
sTemp: String;
bState: Boolean;
i, c: Integer;
app: TSecureApp;
begin
sName := '';
sStatus := 'Out-Of-Date';
sPath := '';
sTime := '';
bState := false;
try
for i := 0 to aList.Count - 1 do
begin
sName := aList[i].sName;
bState := aList[i].nState = WSC_SECURITY_PRODUCT_STATE_ON;
if bState and (sWinVer_ = '11') and sName.Contains('Microsoft') then
begin
// 윈도우 11에서 방화벽 설정 상태를 제대로 가져오지 못하는 문제가 확인됨 22_0826 13:45:00 kku
if fwPolicy2_ = nil then
fwPolicy2_ := CoNetFwPolicy2.Create;
if fwPolicy2_ <> nil then
bState := fwPolicy2_.FirewallEnabled[FW_PROFILE_PERSONAL] and fwPolicy2_.FirewallEnabled[FW_PROFILE_PUBLIC];
end;
sStatus := BooleanToStr(aList[i].nStatus = WSC_SECURITY_PRODUCT_UP_TO_DATE,
'up-to-date', 'out-of-date');
sTime := aList[i].sStateTimestamp;
if sName <> '' then
begin
app := TSecureApp.Create(sName, TYPE_FIREWALL, sStatus, sPath, sTime, bState);
case FwList_.Count of
0 : ;
1 : if FwList_[0].Name.Contains('Windows Firewall') then FwList_.Clear;
else begin
for c := FwList_.Count - 1 downto 0 do
begin
if FwList_[c].Name = app.Name then
begin
FwList_.Delete(c);
break;
end;
end;
end;
end;
FwList_.Add(app);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateFw()');
end;
end;
procedure THandleSecurity.UpdateAs(aList: TWSCProductEntList);
var
sName,
sStatus,
sPath,
sTime,
sTemp: String;
bState: Boolean;
i, c: Integer;
app: TSecureApp;
begin
sName := '';
sStatus := 'Out-Of-Date';
sPath := '';
sTime := '';
bState := false;
try
for i := 0 to aList.Count - 1 do
begin
sName := aList[i].sName;
bState := aList[i].nState = WSC_SECURITY_PRODUCT_STATE_ON;
sStatus := BooleanToStr(aList[i].nStatus = WSC_SECURITY_PRODUCT_UP_TO_DATE,
'up-to-date', 'out-of-date');
sTime := aList[i].sStateTimestamp;
if sName <> '' then
begin
app := TSecureApp.Create(sName, TYPE_AS, sStatus, sPath, sTime, bState);
case AsList_.Count of
0 : ;
else begin
for c := AsList_.Count - 1 downto 0 do
begin
if AsList_[c].Name = app.Name then
begin
AsList_.Delete(c);
break;
end;
end;
end;
end;
AsList_.Add(app);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateAs()');
end;
end;
function THandleSecurity.GetMainAv: TSecureApp;
var
i: Integer;
begin
Result := nil;
case AvList_.Count of
0 : exit;
1 : Result := AvList_[0];
else begin
// 다른 백신 활성화 값이 제대로 매치가 안되서 자꾸 Defender가 보이는 현상있음. 그래서 제외 22_0721 10:51:17 kku
// step 1 : 백신 두개 이상이면 Defender는 후 순위로 가져온다 22_0707 08:45:12 kku
// for i := 0 to AvList_.Count - 1 do
// begin
// if AvList_[i].IsState and not AvList_[i].Name.Contains('Defender') then
// begin
// Exit(AvList_[i]);
// end;
// end;
// step 2 : 활성화 된 것
// for i := 0 to AvList_.Count - 1 do
// begin
// if AvList_[i].IsState then
// begin
// Exit(AvList_[i]);
// end;
// end;
// step 3 : Defneder 아닌 것
for i := 0 to AvList_.Count - 1 do
begin
if not AvList_[i].Name.Contains('Defender') then
begin
Exit(AvList_[i]);
end;
end;
// step 4 : 그냥 첫번째
Result := AvList_[0];
// if AvList_[0].Name.Contains('Defender') then
// Exit(AvList_[0])
// else
// Exit(AvList_[1]);
end;
end;
end;
function THandleSecurity.GetMainFw: TSecureApp;
var
i: Integer;
begin
Result := nil;
case FwList_.Count of
0 : exit;
1 : Result := FwList_[0];
else begin
for i := 0 to FwList_.Count - 1 do
begin
if FwList_[i].IsState then
begin
Exit(FwList_[i]);
end;
end;
Result := FwList_[0];
end;
end;
end;
function THandleSecurity.GetMainAs: TSecureApp;
var
i: Integer;
begin
Result := nil;
case AsList_.Count of
0 : exit;
1 : Result := AsList_[0];
else begin
for i := 0 to AsList_.Count - 1 do
begin
if AsList_[i].IsState then
begin
Exit(AsList_[i]);
end;
end;
Result := AsList_[0];
end;
end;
end;
function THandleSecurity.HasV3: Boolean;
var
i: Integer;
begin
try
Result := false;
for i := 0 to AvList_.Count - 1 do
begin
if Pos('V3', UpperCase(AvList_[i].Name)) > 0 then
begin
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. HasV3()');
end;
end;
end.