BSOne.SFC/Tocsg.Module/FasooDRM/Tocsg.Fasoo.pas

528 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{*******************************************************}
{ }
{ Tocsg.Fasoo }
{ }
{ Copyright (C) 2024 kku }
{ }
{*******************************************************}
unit Tocsg.Fasoo;
interface
uses
Tocsg.Obj, System.SysUtils, Winapi.Windows, System.Classes;
const
{$IFDEF WIN64}
DLL_FASOO = 'WorkPackagerV3_64.dll';
{$ELSE}
DLL_FASOO = 'WorkPackagerV3.dll';
{$ENDIF}
FASOO_COM_OLD = 'WorkPackager.WorkPackagerADK'; // 구버전, CJ에서 사용
FASOO_COM = 'WorkPackagerV3.WorkPackagerADK'; // 새버전, 2020년 4월 부터 변경됐다고 함, 삼성중공업에서 사용
DSD_CODE_LOTTEMART = '0100000000002054'; // 롯데마트
DSD_CODE_SHI = '0000000000001833'; // 삼성중공업
DSD_CODE_CJ = '0000000000002519'; // CJ
DSD_CODE_WFNI = '0100000000004457'; // 웰릭스에프앤아이 (구 웰컴에프앤디)
DSD_CODE_WFND = '0100000000001803'; // 웰컴에프앤디
DSD_CODE_GIORDANO = '0100000000004318'; // 지오다노
const
// Error Code (FED4.0, FED5.0 공통)
E_SERVERID_NOT_EXIST = 3; // server id가 입력되지 않았을 경우
E_INVALID_PARAM = 4; // 필수 인자값이 입력되지 않았을 경우
E_REQ_INFO_NOT_EXIST = 16; // Home Dir이 입력되지 않거나 필수 속성이 존재하지 않을 경우
E_INVALID_FILE_EXT_NSPRT = 11; // 지원하지 않는 파일 확장자
E_FILE_NOT_EXIST = 20; // 파일이 존재하지 않을 경우.
E_FILE_SIZE_ZERO = 21; // 파일 크기가 0일 경우
E_FILE_OPEN_FAIL = 22; // 파일 열람에 실패할 경우.
E_FILE_READ_FAIL = 23; // 파일 읽기에 실패할 경우
E_PACKAGED_FILE = 26; // FSD 파일
E_OLD_OLE_FILE = 27; // 지원하지 않는 OLE 파일 타입.
E_NOT_PACKAGED_FILE = 29; // 일반 파일
E_FILE_DELETE_FAIL = 30; // 파일 삭제에 실패할 경우
E_CHECK_CERTIFICATE_FAIL = 40; // 인증서가 없거나 유효하지 않을 경우
E_COCREATE_INST_FAIL = 41; // COM 객체 생성 실패
E_DECODING_FAIL = 51; // 디코딩 실패
E_SYMMDEC_FAIL = 54; // 암호화 실패
E_MEMALLOCFAIL = 70; // 메모리 할당 실패
E_NOT_INITIALIZE = 72; // 메모리 초기화 실패
// Error Code 참조 (FED5.0 전용)
SC_FILE_FED5_PACKAGED = 1150; // FED5.0 FSD 문서
SC_FILE_FED5_FSN_PACKAGED = 1151; // FED5.0 FSN 문서
SC_FILE_FED5_FSE_PACKAGED = 1152; // FED5.0 FSE 문서
SC_FILE_FED5_NX_PACKAGED = 1153; // FED5.0 NX 문서
SC_NOT_SUPPORT_RIGHT = 1166; // 문서 타입 변환시 해당 문서에 CONVERSION 또는 SAVE 권한이 없을 경우
SC_DISABLED_LOGGING = 1167; // 로그 전송 설정이 되어 있지 않거나 인증서가 설정되어 있지 않을 경우
SC_NOT_FED_VERSION = 1176; // conf 파일의 [PACKAGER] 필드에 VERSION 값이 존재하지 않을 경우 (FED4.0 conf 파일에는 해당값이 존재하지 않음)
SC_FAILED_GET_RIGHTS = 1178; // 문서 복호화시 서버나 클라이언트에 복호화 권한 확인시 권한이 없거나 권한 확인에 실패할 경우
SC_NOT_SUPPORT_ALGORITHM = 1180; // 지원하지 않는 알고리즘
SC_FAILED_SECTION_FIND = 1201; // 문서 헤더에서 섹션을 찾는데 실패할 경우
SC_FAILED_HMAC_COMPARE = 1205; // 문서 헤더의 HMAC 확인에 실패할 경우 (문서 헤더 위변조 여부 확인)
SC_FAILED_GET_DOMAINKEY = 1214; // 인증서에서 도메인키를 가져오는데 실패할 경우
SC_DISCARD_APPCERT = 1216; // 폐기된 인증서를 호출할 경우
SC_DISCARD_DKCOUNT = 1217; // 폐기된 도메인키 카운트를 적용할 경우
SC_FAILED_CERT_SIGN = 1500; // cert에 실패할 경우
SC_FAILED_GET_KEY = 1501; // 키를 가져오는데 실패할 경우
SC_FAILED_PFX_LOAD = 1502; // 인증서 로드에 실패할 경우
SC_FAILED_GET_APPKEY = 1503; // 응용서버 인증서 디코드에 실패할 경우
type
TTgFasoo = class(TTgObject)
private
nVer_: Integer; // 0 = COM 개체 획득 못함, 1 = 올드, 2 = 2020년 4월 이후
ComObj_: Variant;
sFsdFsnPath_, // FSN 문서 복호화 키(폴더) 경로
sFsdNxPath_, // NX 문서 복호화 키(폴더) 경로
sFixedCPID_: String; // CPID(구 Server ID)를 고정해서 사용할때 사용
public
Constructor Create(sFsdFsnPath: String; sFsdNxPath: String = '');
function IsReady: Boolean;
function GetFileType(sEncPath: String): Integer;
function GetFileHeader(sEncPath: String): String;
function IsPackageFile(sEncPath: String): Boolean;
// 복호화
function DoExtract(sEncPath, sDecPath: String; bLogonUser: Boolean = false; pnResult: PInteger = nil): Boolean;
// 암호화
function DoPackagingFsn(sSrcPath, sDestPath: String; pnResult: PInteger = nil): Boolean;
function DoPackagingFsn2(sSrcPath, sDestPath: String; pnResult: PInteger = nil): Boolean;
function DoPackaging(sSrcPath, sDestPath: String; pnResult: PInteger = nil): Boolean;
end;
{$IFDEF _CJ_}
function IsFasooLogon: Integer;
function GetFasooUserID: String;
{$ENDIF}
procedure SetDSD_CODE(sCode: String);
var
DSD_CODE: String = DSD_CODE_LOTTEMART;
// 암호화 시 사용
_sWriteId_: String = 'dlpadmin';// 'csm_tocsg';;
_sWriteName: String = 'dlpadmin';//'최성민';
_sWriteDeptCode: String = 'COMPANY';
_sWriteDeptName: String = 'DeptName';
_sSecurityLevel: String = 'a890dab1a2964ddfba69a04c3d4431ba';
implementation
uses
{$IFDEF _CJ_}
Winapi.ActiveX, F_SSOLib_TLB,
{$ENDIF}
System.Win.ComObj, System.Variants, Tocsg.Safe, Tocsg.Exception, Tocsg.Strings;
procedure SetDSD_CODE(sCode: String);
begin
DSD_CODE := sCode;
if DSD_CODE = DSD_CODE_LOTTEMART then
begin
_sWriteDeptName := '롯데마트';
_sSecurityLevel := 'a890dab1a2964ddfba69a04c3d4431ba';
end else
if DSD_CODE = DSD_CODE_WFNI then
begin
_sWriteId_ := 'admin';
_sWriteName := 'admin';
_sWriteDeptName := '웰릭스에프앤아이'; //'웰컴에프앤디';
// _sSecurityLevel := '39e43183f99f4170be6227255a07dadd'; // 기본보안등급
_sSecurityLevel := '320ce4ed95a34221be960d8f362cbcce'; // 개인정보등급
end else
if DSD_CODE = DSD_CODE_WFND then
begin
_sWriteId_ := 'admin';
_sWriteName := 'admin';
_sWriteDeptName := '웰컴에프앤디';
// _sSecurityLevel := '39e43183f99f4170be6227255a07dadd'; // 기본보안등급
_sSecurityLevel := '320ce4ed95a34221be960d8f362cbcce'; // 개인정보등급
end else begin
_sWriteDeptName := 'Unknown';
_sSecurityLevel := '';
end;
end;
{ TTgFasoo }
Constructor TTgFasoo.Create(sFsdFsnPath: String; sFsdNxPath: String = '');
procedure Init;
begin
// try
// ComObj_ := CreateOleObject(FASOO_COM_OLD);
// nVer_ := 1;
// except
// on E: Exception do
// ETgException.TraceException(Self, E, Format('Create() .. Fail load .. "%s"', [FASOO_COM_OLD]));
// end;
if nVer_ <= 0 then
begin
try
ComObj_ := CreateOleObject(FASOO_COM);
nVer_ := 2;
_Trace('Create() .. Success');
except
on E: Exception do
ETgException.TraceException(Self, E, Format('Create() .. Fail load .. "%s"', [FASOO_COM]));
end;
end;
end;
begin
Inherited Create;
nVer_ := -1;
ComObj_ := varEmpty;
sFixedCPID_ := '';
sFsdFsnPath_ := sFsdFsnPath;
if sFsdNxPath = '' then
sFsdNxPath := sFsdFsnPath;
sFsdNxPath_ := sFsdNxPath;
Init;
if (nVer_ = 2) and (DirectoryExists(sFsdNxPath_)) then // 2020년 이후 신버전
sFixedCPID_ := DSD_CODE;
end;
function TTgFasoo.IsReady: Boolean;
begin
Result := nVer_ <> -1;
end;
function TTgFasoo.GetFileType(sEncPath: String): Integer;
begin
try
if not VarIsEmpty(ComObj_) then
Result := ComObj_.GetFileType(sEncPath)
else
Result := -1;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. GetFileType()');
end;
end;
function TTgFasoo.GetFileHeader(sEncPath: String): String;
begin
if not VarIsEmpty(ComObj_) then
Result := ComObj_.GetFileHeader(sEncPath)
else
Result := '';
end;
function TTgFasoo.IsPackageFile(sEncPath: String): Boolean;
begin
if not VarIsEmpty(ComObj_) then
Result := ComObj_.IsPackageFile(sEncPath) = 1
else
Result := false;
end;
function TTgFasoo.DoExtract(sEncPath, sDecPath: String; bLogonUser: Boolean = false; pnResult: PInteger = nil): Boolean;
var
nType, nResult: Integer;
sCPID,
sFHeader,
sFsdPath: String;
FHeaderList: TStringList;
begin
Result := false;
try
nResult := -1;
if pnResult <> nil then
pnResult^ := -1;
if nVer_ = 0 then
exit;
if VarIsEmpty(ComObj_) then
exit;
if not FileExists(sEncPath) then
exit;
sFsdPath := '';
nType := GetFileType(sEncPath);
case nType of
103 : // FSN
begin
if DirectoryExists(sFsdFsnPath_) then
sFsdPath := sFsdFsnPath_;
end;
106 : // NX
begin
if DirectoryExists(sFsdNxPath_) then
sFsdPath := sFsdNxPath_;
end
else exit;
end;
if sFsdPath = '' then
exit;
if FileExists(sDecPath) then
DeleteFile(PChar(sDecPath));
// 타사 고객사/계열사 암호화 파일인지 체크하도록 변경 25_0414 13:58:51 kku
// sCPID := sFixedCPID_;
// if sCPID = '' then
begin
sFHeader := GetFileHeader(sEncPath);
if sFHeader = '' then
exit;
Guard(FHeaderList, TStringList.Create);
SplitString(sFHeader, ';', FHeaderList, true);
if FHeaderList.Count < 18 then
exit;
sCPID := FHeaderList[17]; // 18번째에 있음
end;
// ServerID 체크 추가 25_0408 09:23:39 kku
// ServerID가 다른 암호화 파일을 복호화 시도하면 "타사 제품으로 암호화된 문서이므로 열람 할 수 없습니다."라는 메시지가 나온다고 함
if DSD_CODE <> sCPID then
begin
if pnResult <> nil then
pnResult^ := -2;
_Trace('Fail .. DoExtract() .. Invalid ServerID, Get=%s, Chk=%s', [sCPID, DSD_CODE], 3);
exit;
end;
if bLogonUser then
nResult := ComObj_.DoExtract_c(sFsdPath, sCPID, sEncPath, sDecPath, 'VIEW')
else
nResult := ComObj_.DoExtract(sFsdPath, sCPID, sEncPath, sDecPath);
if pnResult <> nil then
pnResult^ := nResult;
Result := FileExists(sDecPath);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoExtract()');
end;
end;
function TTgFasoo.DoPackagingFsn(sSrcPath, sDestPath: String; pnResult: PInteger = nil): Boolean;
var
nResult: Integer;
begin
Result := false;
nResult := -1;
if pnResult <> nil then
pnResult^ := -1;
if nVer_ = 0 then
exit;
if _sSecurityLevel = '' then
exit;
if VarIsEmpty(ComObj_) then
exit;
if not FileExists(sSrcPath) then
exit;
if not DirectoryExists(sFsdFsnPath_) then
exit;
case GetFileType(sSrcPath) of
103 : exit; // FSN
106 : exit; // NX
end;
if FileExists(sDestPath) then
DeleteFile(PChar(sDestPath));
try
nResult := ComObj_.DoPackagingFsn(sFsdFsnPath_, DSD_CODE,
sSrcPath, sDestPath,
ExtractFileName(sSrcPath), _sWriteId_,
_sWriteName, _sWriteId_,
_sWriteName, _sWriteDeptCode,
_sWriteDeptName, _sWriteId_,
_sWriteName, _sWriteDeptCode,
_sWriteDeptName,
_sSecurityLevel);
if pnResult <> nil then
pnResult^ := nResult;
Result := FileExists(sDestPath);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoPackagingFsn()');
end;
end;
function TTgFasoo.DoPackagingFsn2(sSrcPath, sDestPath: String; pnResult: PInteger = nil): Boolean;
var
nType,
nResult: Integer;
begin
Result := false;
nResult := -1;
if pnResult <> nil then
pnResult^ := -1;
if nVer_ = 0 then
exit;
if _sSecurityLevel = '' then
exit;
if VarIsEmpty(ComObj_) then
exit;
if not FileExists(sSrcPath) then
exit;
if not DirectoryExists(sFsdFsnPath_) then
exit;
nType := GetFileType(sSrcPath);
// _Trace('DoPackagingFsn2() .. 5, Type=%d', [nType]);
case GetFileType(sSrcPath) of
103 : exit; // FSN
106 : exit; // NX
end;
// _Trace('DoPackagingFsn2() .. 6');
if FileExists(sDestPath) then
DeleteFile(PChar(sDestPath));
try
nResult := ComObj_.DoPackagingFsn2(sFsdFsnPath_, DSD_CODE,
sSrcPath, sDestPath,
ExtractFileName(sSrcPath), _sWriteId_,
_sWriteName, _sWriteId_,
_sWriteName, _sWriteDeptCode,
_sWriteDeptName, _sWriteId_,
_sWriteName, _sWriteDeptCode,
_sWriteDeptName,
_sSecurityLevel);
if pnResult <> nil then
pnResult^ := nResult;
Result := FileExists(sDestPath);
// _Trace('DoPackagingFsn2() .. 7');
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoPackagingFsn2()');
end;
end;
function TTgFasoo.DoPackaging(sSrcPath, sDestPath: String; pnResult: PInteger = nil): Boolean;
var
nResult: Integer;
begin
Result := false;
nResult := -1;
if pnResult <> nil then
pnResult^ := -1;
if nVer_ = 0 then
exit;
if _sSecurityLevel = '' then
exit;
if VarIsEmpty(ComObj_) then
exit;
if not FileExists(sSrcPath) then
exit;
if not DirectoryExists(sFsdFsnPath_) then
exit;
case GetFileType(sSrcPath) of
103 : exit; // FSN
106 : exit; // NX
end;
if FileExists(sDestPath) then
DeleteFile(PChar(sDestPath));
try
nResult := ComObj_.DoPackaging(sFsdFsnPath_, DSD_CODE,
sSrcPath, sDestPath,
ExtractFileName(sSrcPath),
_sWriteId_, _sWriteName,
'', '', '', '', '');
if pnResult <> nil then
pnResult^ := nResult;
Result := FileExists(sDestPath);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DoPackagingFsn2()');
end;
end;
{$IFDEF _CJ_}
var
USER_KEY: String = 'CUID';
// 실패 : -1
// 로그온 : 1
// 로그오프 : 0
function IsFasooLogon: Integer;
var
hr: HResult;
iSSO: IxSSO;
begin
Result := -1;
try
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
try
iSSO := nil;
hr := CoCreateInstance(CLASS_FasooSSO, nil, CLSCTX_INPROC_SERVER, IID_IxSSO, iSSO);
if SUCCEEDED(hr) and (iSSO <> nil) then
Result := iSSO.IsLogon(DSD_CODE);
finally
CoUninitialize;
end;
except
// ..
end;
end;
// 로그 아웃 상태에서 시도하면 파수 로그인창이 뜨면서 "빈값"을 반환함
function GetFasooUserID: String;
var
hr: HResult;
iSSO: IxSSO;
begin
Result := '*Fail%_';
// Result := '';
try
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
try
iSSO := nil;
hr := CoCreateInstance(CLASS_FasooSSO, nil, CLSCTX_INPROC_SERVER, IID_IxSSO, iSSO);
if SUCCEEDED(hr) and (iSSO <> nil) then
Result := iSSO.GetUserInfo(DSD_CODE, USER_KEY);
finally
CoUninitialize;
end;
except
// ..
end;
end;
{$ENDIF}
end.