Compare commits

...

6 Commits

Author SHA1 Message Date
4d9e136166 Updated bug
All checks were successful
Build / build-windows-binary (push) Successful in 30s
Build / build-linux-binary (push) Successful in 48s
2024-08-26 14:25:47 -05:00
603bc13683 feat(doc strings) #18 Add documentation to all functions in code
All checks were successful
Build / build-windows-binary (push) Successful in 33s
Build / build-linux-binary (push) Successful in 1m52s
2024-08-26 14:21:29 -05:00
394c276131 fix(home directory) #15 home directory not correct 2024-08-26 13:50:35 -05:00
cb96b00e8d feat(config) #10 add config.toml to releases 2024-08-26 13:25:20 -05:00
abd669c3bb Merge pull request 'fix(authentication): BUG #20 - Authentication isnt working with existing logic & updated model' (#21) from fix-first-time-auth-error into main
All checks were successful
Build / build-windows-binary (push) Successful in 34s
Build / build-linux-binary (push) Successful in 1m23s
Reviewed-on: #21
2024-08-22 14:07:43 -05:00
487d883297 fix(authentication): BUG #20 - Authentication isnt working with existing logic & updated model 2024-08-22 14:04:00 -05:00
8 changed files with 237 additions and 104 deletions

View File

@ -38,4 +38,6 @@ jobs:
- run: pyinstaller --noconfirm --onefile --console ${{ gitea.workspace }}/inex.py - run: pyinstaller --noconfirm --onefile --console ${{ gitea.workspace }}/inex.py
- uses: softprops/action-gh-release@v2 - uses: softprops/action-gh-release@v2
with: with:
files: ${{ gitea.workspace }}/dist/inex.exe files: |
${{ gitea.workspace }}/dist/inex.exe
${{ gitea.workspace }}/config.toml.example

View File

@ -2,19 +2,19 @@
selectedPlatform = "dev" selectedPlatform = "dev"
[output] [output]
pushToplatform = true pushToplatform = false
dumpTojson = true dumpTojson = true
filename ="./data.json" filename ="./data.json"
token = "./.token" token = "./.token"
[logging] [logging]
use_log = true useLog = true
logLevel = "debug" logLevel = "debug"
logPath = "./inex.log" logPath = "./inex.log"
[database] [database]
overrideEmbeddedquery = false overrideEmbeddedquery = false
daysTopull = 10 daysTopull = 20
driver = "ODBC Driver 18 for SQL Server" driver = "ODBC Driver 18 for SQL Server"
server = "192.168.x.x" server = "192.168.x.x"
database = "EFTDB" database = "EFTDB"
@ -22,7 +22,7 @@ user = "a"
password = "a" password = "a"
query = """DECLARE @stopTime DATETIME2 query = """DECLARE @stopTime DATETIME2
SET @stopTime=DATEADD(DAY, -30, GETDATE()) SET @stopTime=DATEADD(DAY, -30, GETDATE())
SELECT p.ProtocolCommandID, t.Time_stamp, p.RemoteIP, p.RemotePort, p.LocalIP, p.LocalPort, p.Protocol, p.SiteName, p.Command, p.FileName, p.VirtualFolderName, p.FileSize, p.TransferTime, p.BytesTransferred, p.Description, p.ResultID, t.TransactionID, p.Actor, t.TransactionObject, t.NodeName, t.TransactionGUID, a.Protocol user_type SELECT p.ProtocolCommandID, t.Time_stamp, p.RemoteIP, p.RemotePort, p.LocalIP, p.LocalPort, p.Protocol, p.SiteName, p.Command, p.FileName, p.PhysicalFolderName, p.VirtualFolderName, p.FileSize, p.TransferTime, p.BytesTransferred, p.Description, p.ResultID, t.TransactionID, p.Actor, t.TransactionObject, t.NodeName, t.TransactionGUID, a.Protocol user_type
FROM tbl_Transactions t FROM tbl_Transactions t
Full JOIN tbl_ProtocolCommands p ON(t.TransactionID=p.TransactionID) Full JOIN tbl_ProtocolCommands p ON(t.TransactionID=p.TransactionID)
Full JOIN tbl_Authentications a ON(t.TransactionID=a.TransactionID) Full JOIN tbl_Authentications a ON(t.TransactionID=a.TransactionID)
@ -50,7 +50,5 @@ client_id = "eft-event-generator-confidential"
secret = "" secret = ""
[immutables] [immutables]
prd_instance_id = 1 product_name = "GlobalScape EFT"
product_guid = "asdf" prd_ext_tenant_name = "GlobalScape EFT"
product_name = "EFT"
product_version ="8.1.0.9"

29
inex.py
View File

@ -13,7 +13,10 @@ import inexSqlquery
class Inex: class Inex:
def __init__(self): def __init__(self):
"""Initilize config, calls functions from inex-connect.py and inex-logging.py""" """Initilize config, calls functions from inexConnect.py, inexLogging.py
inexDataModel.py, inexDataProcessing.py, inexEncoder.py and inexSqlquery.py
Main logic of the program. Requires a config.toml in the same directory it's
being run from."""
# assign libraries # assign libraries
self.db = pyodbc self.db = pyodbc
self.il = logging self.il = logging
@ -25,6 +28,7 @@ class Inex:
self.e = inexEncoder.Encoder self.e = inexEncoder.Encoder
self.sq = inexSqlquery self.sq = inexSqlquery
# Check if local config file exists.
if self.os.path.exists('./config.toml'): if self.os.path.exists('./config.toml'):
config_file_path = './config.toml' config_file_path = './config.toml'
with open(config_file_path, 'rb') as c: with open(config_file_path, 'rb') as c:
@ -43,18 +47,19 @@ class Inex:
self.useLog = self.config["logging"]["useLog"] self.useLog = self.config["logging"]["useLog"]
self.logPath = self.config["logging"]["logPath"] self.logPath = self.config["logging"]["logPath"]
self.logLevel = self.config["logging"]["logLevel"] self.logLevel = self.config["logging"]["logLevel"]
self.prdInstanceID = self.config["immutables"]["prd_instance_id"] self.prdExttenantname = self.config["immutables"]["prd_ext_tenant_name"]
self.productGUID = self.config["immutables"]["product_guid"]
self.productName = self.config["immutables"]["product_name"] self.productName = self.config["immutables"]["product_name"]
self.productVersion = self.config["immutables"]["product_version"]
self.tokenFilepath = self.config["output"]["token"] self.tokenFilepath = self.config["output"]["token"]
self.selectedPlatform = self.config["fortraPlatform"]["selectedPlatform"] self.selectedPlatform = self.config["fortraPlatform"]["selectedPlatform"]
self.writeJsonfile = self.config["output"]["dumpTojson"] self.writeJsonfile = self.config["output"]["dumpTojson"]
self.pushToplatform = self.config["output"]["pushToplatform"] self.pushToplatform = self.config["output"]["pushToplatform"]
self.queryOverride = self.config["database"]["overrideEmbeddedquery"] self.queryOverride = self.config["database"]["overrideEmbeddedquery"]
self.queryDaystopull = self.config["database"]["daysTopull"] self.queryDaystopull = self.config["database"]["daysTopull"]
except: except Exception as e:
print("No config.toml. Please use example file and configure appropriately") print("No config.toml or possibly missing settings in the file. Please use config.toml.example file and configure appropriately")
self.il.error(e)
print(e)
exit(1) exit(1)
if "dev" in self.selectedPlatform.lower(): if "dev" in self.selectedPlatform.lower():
@ -70,18 +75,20 @@ class Inex:
# create the connection to the database # create the connection to the database
self.cursor = self.ic.inexSql.connectDatabase(self, self.db, self.dbDriver, self.dbServer, self.dbDatabase, self.dbUser, self.dbPassword) self.cursor = self.ic.inexSql.connectDatabase(self, self.db, self.dbDriver, self.dbServer, self.dbDatabase, self.dbUser, self.dbPassword)
# Query the database
self.data = self.ic.inexSql.databaseQuery(self, self.cursor, self.sq.sqlQuerymodel.queryData(self.queryOverride,self.dbQuery, self.queryDaystopull)) self.data = self.ic.inexSql.databaseQuery(self, self.cursor, self.sq.sqlQuerymodel.queryData(self.queryOverride,self.dbQuery, self.queryDaystopull))
self.modifiedData = processData(self.data, dataTemplate, prd_instance_id=self.prdInstanceID,\ # Modify the data to meet EFC requirements
product_guid=self.productGUID,product_name=self.productName,product_version=self.productVersion) self.modifiedData = processData(self.data, dataTemplate, prd_ext_tenant_name=self.prdExttenantname,product_name=self.productName,\
prd_ext_tenant_id=self.platformConfig["tenant_id"])
# Push data to EFC. Check for local Auth token -> Authenticate if needed -> push data
if self.pushToplatform: if self.pushToplatform:
inexConnect.fortraEFC.pushPayload(self) inexConnect.fortraEFC.__init__(self)
# TODO: move this to its own function
if self.useLog: if self.useLog:
self.il.warning(f"Writing to '{self.outputFile}'.") self.il.warning(f"Writing to '{self.outputFile}'.")
# Write data to json
if self.writeJsonfile: if self.writeJsonfile:
with open(self.outputFile, "w") as f: with open(self.outputFile, "w") as f:
self.j.dump(self.modifiedData, f, indent = 2, cls=self.e) self.j.dump(self.modifiedData, f, indent = 2, cls=self.e)

View File

@ -20,6 +20,7 @@ class inexSql:
return cursor return cursor
def databaseQuery(self, cursor, query, args=()): def databaseQuery(self, cursor, query, args=()):
"""Use the database connection to send a query."""
if self.useLog: if self.useLog:
self.il.debug(f"Query:") self.il.debug(f"Query:")
self.il.debug(query) self.il.debug(query)
@ -43,33 +44,54 @@ class inexSql:
return r return r
class fortraEFC: class fortraEFC:
def getToken(self): """Class to connect to fortra EFC. It will authenticate and push rest payloads.
self.tokenData = self.r.post(self.platformConfig["idp"], data={"grant_type":"client_credentials",\ Writes a .token file to the same directory script was run in."""
"client_id": self.platformConfig["client_id"],\ def __init__(self):
"client_secret": self.platformConfig["secret"],}) """This is the logic for how authentication is handled"""
def writeToken(self): # Check if .token file is present
fortraEFC.getToken(self) if fortraEFC.readToken(self) == 1:
with open(self.tokenFilepath, "w") as f: # Get fresh token. First run.
self.j.dump(self.tokenData.json(), f, indent = 2) fortraEFC.getToken(self)
fortraEFC.writeToken(self)
# Push data with token
self.pushPayloadresponse = fortraEFC.pushPayload(self)
if self.pushPayloadresponse == 401:
fortraEFC.getToken(self)
fortraEFC.writeToken(self)
fortraEFC.pushPayload(self)
def readToken(self): def readToken(self):
"""Looks locally for a .token file. Returns a numeral code
for logic in the init method."""
if self.os.path.exists(self.tokenFilepath): if self.os.path.exists(self.tokenFilepath):
with open(self.tokenFilepath, 'rb') as t: with open(self.tokenFilepath, 'rb') as t:
self.tokenData = self.j.load(t) self.tokenData = self.j.load(t)
# print(self.tokenData["access_token"]) self.il.debug(f'readToken {self.tokenData["access_token"]}')
return 0
else: else:
fortraEFC.writeToken(self) return 1
def getToken(self):
"""Gets a token from fortra idp."""
self.tokenData = self.r.post(self.platformConfig["idp"], data={"grant_type":"client_credentials",\
"client_id": self.platformConfig["client_id"],\
"client_secret": self.platformConfig["secret"],})
self.tokenData = self.tokenData.json()
self.il.debug(f'getToken {self.tokenData["access_token"]}')
def writeToken(self):
"""Writes a token to a local file named '.token'."""
fortraEFC.getToken(self)
with open(self.tokenFilepath, "w") as f:
self.j.dump(self.tokenData, f, indent = 2)
self.il.debug(f'writeToken {self.tokenData["access_token"]}')
def pushPayload(self): def pushPayload(self):
fortraEFC.readToken(self) """Sends data to fortra EFC. Requires a token from the idp."""
print(self.tokenData) self.il.debug(f'pushPayload {self.tokenData["access_token"]}')
try: url = f'{self.platformConfig["efc_url"]}/api/v1/unity/data/{self.platformConfig["tenant_id"]}/machine_event'
url = f'{self.platformConfig["efc_url"]}/api/v1/unity/data/{self.platformConfig["tenant_id"]}/machine_event' pushPayloadResponse = self.r.post(url, headers={'Authorization': f'Bearer {self.tokenData["access_token"]}'},\
pushPayloadResponse = self.r.post(url, headers={'Authorization': f'bearer {self.tokenData["access_token"]}'},\ data=self.j.dumps(self.modifiedData, cls=self.e))
json=self.j.dumps(self.modifiedData,indent = 2, cls=self.e)) self.il.debug(pushPayloadResponse.status_code)
return pushPayloadResponse.status_code self.il.debug(pushPayloadResponse.text)
except self.r.exceptions.HTTPError as errh: return pushPayloadResponse.status_code
print ("Http Error:",errh)
if "401" in errh:
fortraEFC.writeToken(self)
fortraEFC.pushPayload(self)

View File

@ -1,6 +1,10 @@
def dataTemplate(transactionType,**kwargs): def dataTemplate(transactionType,**kwargs):
uploadDownload = { """Created templates for use. This function forms json data into an
"bytes" : kwargs.get('bytes_out'), appropriate model for EFC. It returnes the appropriate template based
on the transaction type passed into the function. The logic to process
this is at the bottom of the function."""
upload = {
"bytes" : kwargs.get('bytes'),
"dst_endpoint": { "dst_endpoint": {
"port": kwargs.get('dst_endpoint_port'), "port": kwargs.get('dst_endpoint_port'),
"ip": kwargs.get('dst_endpoint_ip'), "ip": kwargs.get('dst_endpoint_ip'),
@ -8,16 +12,17 @@ def dataTemplate(transactionType,**kwargs):
}, },
"duration": kwargs.get('duration'), "duration": kwargs.get('duration'),
"file": { "file": {
"created_time": kwargs.get('time'), "created_time": kwargs.get('file_created_time'),
"uid": kwargs.get('file_uid'),
"size": kwargs.get('file_size'), "size": kwargs.get('file_size'),
"name": kwargs.get('file_name'), "name": kwargs.get('file_name'),
"path": kwargs.get('file_path') "path": kwargs.get('file_path')
}, },
"guid": kwargs.get('guid'), "guid": kwargs.get('file_uid'),
"node_name": kwargs.get('node_name'), "node_name": kwargs.get('node_name'),
"prd_ext_tenant_id": kwargs.get('tenant'), "prd_ext_tenant_id": kwargs.get('prd_ext_tenant_id'),
"product_name": "GlobalScape EFT", "product_name": kwargs.get('product_name'),
"prd_ext_tenant_name": "GlobalScape EFT", "prd_ext_tenant_name": kwargs.get('prd_ext_tenant_name'),
"classifications": [{ "classifications": [{
"ref_id": f"globalscape:{kwargs.get('guid')}", "ref_id": f"globalscape:{kwargs.get('guid')}",
"time": kwargs.get('time'), "time": kwargs.get('time'),
@ -31,15 +36,61 @@ def dataTemplate(transactionType,**kwargs):
"ip": kwargs.get('src_endpoint_ip'), "ip": kwargs.get('src_endpoint_ip'),
"type": kwargs.get('src_endpoint_type') "type": kwargs.get('src_endpoint_type')
}, },
"tenant": kwargs.get('tenant'), "tenant": kwargs.get('prd_ext_tenant_id'),
"tenant_name":"GlobalScape", "tenant_name":"GlobalScape",
"time": kwargs.get('time'), "time": kwargs.get('time'),
"status_code": kwargs.get('status_code'), "status_code": kwargs.get('status_code'),
"status_detail": kwargs.get('description'), "status_detail": kwargs.get('status_detail'),
"user": { "user": {
"home_directory": kwargs.get('user_home_directory'), "home_directory": kwargs.get('user_home_directory'),
"uuid": kwargs.get('guid'), "uuid": kwargs.get('guid'),
"uid": kwargs.get('uid'), "uid": kwargs.get('user_uid'),
"type": kwargs.get('user_type'),
"name": kwargs.get('user_name')
},
"utype": kwargs.get('utype')
}
download = {
"bytes" : kwargs.get('bytes'),
"dst_endpoint": {
"port": kwargs.get('dst_endpoint_port'),
"ip": kwargs.get('dst_endpoint_ip'),
"type": kwargs.get('dst_endpoint_type')
},
"duration": kwargs.get('duration'),
"file": {
"uid": kwargs.get('file_uid'),
"size": kwargs.get('file_size'),
"name": kwargs.get('file_name'),
"path": kwargs.get('file_path')
},
"guid": kwargs.get('file_uid'),
"node_name": kwargs.get('node_name'),
"prd_ext_tenant_id": kwargs.get('prd_ext_tenant_id'),
"product_name": kwargs.get('product_name'),
"prd_ext_tenant_name": kwargs.get('prd_ext_tenant_name'),
"classifications": [{
"ref_id": f"globalscape:{kwargs.get('guid')}",
"time": kwargs.get('time'),
}],
"session": {
"created_time": kwargs.get('time'),
"uid": kwargs.get('session_uid')
},
"src_endpoint": {
"port": kwargs.get('src_endpoint_port'),
"ip": kwargs.get('src_endpoint_ip'),
"type": kwargs.get('src_endpoint_type')
},
"tenant": kwargs.get('prd_ext_tenant_id'),
"tenant_name":"GlobalScape",
"time": kwargs.get('time'),
"status_code": kwargs.get('status_code'),
"status_detail": kwargs.get('status_detail'),
"user": {
"home_directory": kwargs.get('user_home_directory'),
"uuid": kwargs.get('guid'),
"uid": kwargs.get('user_uid'),
"type": kwargs.get('user_type'), "type": kwargs.get('user_type'),
"name": kwargs.get('user_name') "name": kwargs.get('user_name')
}, },
@ -50,16 +101,18 @@ def dataTemplate(transactionType,**kwargs):
"file": { "file": {
"size": kwargs.get('file_size'), "size": kwargs.get('file_size'),
"name": kwargs.get('file_name'), "name": kwargs.get('file_name'),
"path": kwargs.get('file_path') "path": kwargs.get('file_path'),
"uid": kwargs.get('file_uid'),
}, },
"guid": kwargs.get('guid'), "guid": f'deleted:{kwargs.get("guid")}',
"node_name": kwargs.get('node_name'),
"classifications": [{ "classifications": [{
"ref_id": f"globalscape:{kwargs.get('guid')}", "ref_id": f"globalscape:{kwargs.get('guid')}",
"time": kwargs.get('time'), "time": kwargs.get('time'),
}], }],
"prd_ext_tenant_name": "Globalscape EFT", "prd_ext_tenant_name": kwargs.get("prd_ext_tenant_name"),
"prd_ext_tenant_id": kwargs.get('tenant'), "prd_ext_tenant_id": kwargs.get('prd_ext_tenant_id'),
"product_name": "Globalscape EFT", "product_name": kwargs.get("product_name"),
"session": { "session": {
"created_time": kwargs.get('time'), "created_time": kwargs.get('time'),
"uid": kwargs.get('session_uid') "uid": kwargs.get('session_uid')
@ -69,16 +122,20 @@ def dataTemplate(transactionType,**kwargs):
"ip": kwargs.get('src_endpoint_ip'), "ip": kwargs.get('src_endpoint_ip'),
"type": kwargs.get('src_endpoint_type') "type": kwargs.get('src_endpoint_type')
}, },
"tenant": kwargs.get('prd_ext_tenant_id'),
"tenant_name":"GlobalScape",
"dst_endpoint": { "dst_endpoint": {
"port": kwargs.get('dst_endpoint_port'), "port": kwargs.get('dst_endpoint_port'),
"ip": kwargs.get('dst_endpoint_ip'), "ip": kwargs.get('dst_endpoint_ip'),
"type": kwargs.get('dst_endpoint_type') "type": kwargs.get('dst_endpoint_type')
}, },
"time": kwargs.get('time'), "time": kwargs.get('time'),
"status_code": kwargs.get('status_code'),
"status_detail": kwargs.get('status_detail'),
"user": { "user": {
"home_directory": kwargs.get('user_home_directory'), "home_directory": kwargs.get('user_home_directory'),
"uuid": kwargs.get('guid'), "uuid": kwargs.get('user_session_uid'),
"uid": kwargs.get('uid'), "uid": kwargs.get('user_uid'),
"type": kwargs.get('user_type'), "type": kwargs.get('user_type'),
"name": kwargs.get('user_name') "name": kwargs.get('user_name')
}, },
@ -96,9 +153,14 @@ def dataTemplate(transactionType,**kwargs):
"type": kwargs.get('dst_endpoint_type') "type": kwargs.get('dst_endpoint_type')
}, },
"guid": kwargs.get('guid'), "guid": kwargs.get('guid'),
"prd_ext_tenant_id": kwargs.get('tenant'), "node_name": kwargs.get('node_name'),
"product_name": "GlobalScape EFT", "tenant": kwargs.get('prd_ext_tenant_id'),
"prd_ext_tenant_name": "GlobalScape EFT", "tenant_name":"GlobalScape",
"prd_ext_tenant_id": kwargs.get('prd_ext_tenant_id'),
"product_name": kwargs.get("product_name"),
"prd_ext_tenant_name": kwargs.get('prd_ext_tenant_name'),
"status_code": kwargs.get('status_code'),
"status_detail": kwargs.get('status_detail'),
"src_endpoint": { "src_endpoint": {
"port": kwargs.get('src_endpoint_port'), "port": kwargs.get('src_endpoint_port'),
"ip": kwargs.get('src_endpoint_ip'), "ip": kwargs.get('src_endpoint_ip'),
@ -107,18 +169,22 @@ def dataTemplate(transactionType,**kwargs):
"time": kwargs.get('time'), "time": kwargs.get('time'),
"user": { "user": {
"home_directory": kwargs.get('user_home_directory'), "home_directory": kwargs.get('user_home_directory'),
"uuid": kwargs.get('guid'), "uuid": kwargs.get('user_session_uid'),
"uid": kwargs.get('uid'), "uid": kwargs.get('user_uid'),
"type": kwargs.get('user_type'), "type": kwargs.get('user_type'),
"name": kwargs.get('user_name') "name": kwargs.get('user_name')
}, },
"session": {
"created_time": kwargs.get('time'),
"uid": kwargs.get('session_uid')
},
"utype": kwargs.get('utype') "utype": kwargs.get('utype')
} }
if transactionType == "file_uploaded": if transactionType == "file_uploaded":
template = uploadDownload template = upload
if transactionType == "file_downloaded": if transactionType == "file_downloaded":
template = uploadDownload template = download
if transactionType == "file_deleted": if transactionType == "file_deleted":
template = fileDeleted template = fileDeleted
if transactionType == "user_logged_on": if transactionType == "user_logged_on":

View File

@ -1,61 +1,74 @@
def processData(data, template, **kwargs): def processData(data, template, **kwargs):
"""Translates data from sql query to the appropriate place in the respective template. """Translates data from sql query to the appropriate place in the respective template.
Accepts data, which is the sql query output, the template function, and finally Accepts data, which is the sql query output, the template function, and finally
additional data to insert into the template.""" additional data to insert into the template. Uses other functions to further
process row data."""
processedData = [] processedData = []
transactionLoginid = [] transactionLoginid = []
for row in data: for row in data:
# print(f'Row: {row}') # print(f'Row: {row}')
if identifyUtype(row.get('Command')) == "other": # must set variables for the different templates and do logic based on that. Do not call identifyUtype many times
identifyUtypecommand = identifyUtype(row.get('Command'))
if identifyUtypecommand == "other":
continue continue
if row.get('Command') == None: if row.get('Command') == None:
continue continue
userType = identifyUserType(row.get('user_type'))
userHome = parseHomefolder(row.get('Actor'),row.get('VirtualFolderName'))
try: try:
processedData.append(template(identifyUtype(row.get('Command')),\ processedData.append(template(identifyUtypecommand,\
prd_ext_tenant_id='',\ prd_ext_tenant_name=kwargs.get('prd_ext_tenant_name'),\
user_uid=row.get('TransactionID'),\
status_detail=row.get('Description'),\
prd_ext_tenant_id=kwargs.get('prd_ext_tenant_id'),\
status_code=row.get('ResultID'),\ status_code=row.get('ResultID'),\
file_created_time=row.get('Time_stamp'),\
file_size=row.get('FileSize'),\ file_size=row.get('FileSize'),\
file_uid=row.get('ProtocolCommandID'),\
file_path=row.get('PhysicalFolderName'),\ file_path=row.get('PhysicalFolderName'),\
file_virtual_path=row.get('VirtualFolderName'),\
file_name=row.get('FileName'),\ file_name=row.get('FileName'),\
guid=row.get('TransactionGUID'),\ guid=row.get('TransactionGUID'),\
ref_id=row.get('ProtocolCommandID'),\
prd_instance_id=kwargs.get('prd_instance_id'),\
product_guid=kwargs.get('product_guid'),\
product_name=kwargs.get('product_name'),\ product_name=kwargs.get('product_name'),\
product_version=kwargs.get('product_version'),\
node_name=row.get('NodeName'),\ node_name=row.get('NodeName'),\
session_uid=row.get('TransactionID'),\
src_endpoint_type=row.get('Protocol'),\ src_endpoint_type=row.get('Protocol'),\
src_endpoint_port=row.get('RemotePort'),\ src_endpoint_port=row.get('RemotePort'),\
src_endpoint_ip=row.get('RemoteIP'),\ src_endpoint_ip=row.get('RemoteIP'),\
dst_endpoint_port=row.get('LocalPort'),\ dst_endpoint_port=row.get('LocalPort'),\
dst_endpoint_ip=row.get('LocalIP'),\ dst_endpoint_ip=row.get('LocalIP'),\
dst_endpoint_type=row.get('Protocol'),\ dst_endpoint_type=row.get('Protocol'),\
session_uid=row.get('TransactionID'),\ user_session_uid=row.get('TransactionID'),\
bytes_out=row.get('BytesTransferred'),\ bytes=row.get('BytesTransferred'),\
duration=row.get('TransferTime'),\
time=row.get('Time_stamp'),\ time=row.get('Time_stamp'),\
user_type=identifyUserType(row.get('user_type')),\ duration=row.get('TransferTime'),\
user_domain=row.get('SiteName'),\ user_type=userType,\
user_name=row.get('Actor'),\ user_name=row.get('Actor'),\
user_home_directory=row.get('VirtualFolderName'),\ user_home_directory=userHome,\
description=row.get('Description'),\ utype=identifyUtypecommand))
utype=identifyUtype(row.get('Command'))))
except UnboundLocalError: except UnboundLocalError:
print(f'Problem row GUID:{row.get("TransactionGUID")} ::: TransactionObject:{row.get("TransactionObject")} Command: {row.get("Command")}') print(f'Problem row GUID:{row.get("TransactionGUID")} ::: TransactionObject:{row.get("TransactionObject")} Command: {row.get("Command")}')
continue
identifyUtypetransactionObject = identifyUtype(row.get('TransactionObject'))
if identifyUtypetransactionObject == "other":
continue continue
if row.get('TransactionGUID') not in transactionLoginid: if row.get('TransactionGUID') not in transactionLoginid:
try: try:
processedData.append(template(identifyUtype(row.get('TransactionObject')),\ processedData.append(template(identifyUtypetransactionObject,\
prd_ext_tenant_id=kwargs.get('prd_ext_tenant_id'),\
prd_ext_tenant_name=kwargs.get('prd_ext_tenant_name'),\
status_detail=row.get('Description'),\
guid=row.get('TransactionGUID'),\ guid=row.get('TransactionGUID'),\
status_code=row.get('ResultID'),\
node_name=row.get('NodeName'),\
prd_instance_id=kwargs.get('prd_instance_id'),\ prd_instance_id=kwargs.get('prd_instance_id'),\
product_guid=kwargs.get('product_guid'),\
product_name=kwargs.get('product_name'),\ product_name=kwargs.get('product_name'),\
product_version=kwargs.get('product_version'),\
src_endpoint_type=row.get('Protocol'),\ src_endpoint_type=row.get('Protocol'),\
src_endpoint_port=row.get('RemotePort'),\ src_endpoint_port=row.get('RemotePort'),\
src_endpoint_ip=row.get('RemoteIP'),\ src_endpoint_ip=row.get('RemoteIP'),\
@ -63,14 +76,14 @@ def processData(data, template, **kwargs):
dst_endpoint_ip=row.get('LocalIP'),\ dst_endpoint_ip=row.get('LocalIP'),\
dst_endpoint_type=row.get('Protocol'),\ dst_endpoint_type=row.get('Protocol'),\
session_uid=row.get('TransactionID'),\ session_uid=row.get('TransactionID'),\
bytes_out=row.get('BytesTransferred'),\
transfer_time=row.get('TransferTime'),\ transfer_time=row.get('TransferTime'),\
time=row.get('Time_stamp'),\ time=row.get('Time_stamp'),\
user_type=identifyUserType(row.get('user_type')),\ user_session_uid=row.get('TransactionID'),\
user_domain=row.get('SiteName'),\ user_uid=row.get('TransactionID'),\
user_type=userType,\
user_name=row.get('Actor'),\ user_name=row.get('Actor'),\
user_home_directory=row.get('VirtualFolderName'),\ user_home_directory=userHome,\
utype=identifyUtype(row.get('TransactionObject'))\ utype=identifyUtypetransactionObject\
)) ))
transactionLoginid.append(row.get('TransactionGUID')) transactionLoginid.append(row.get('TransactionGUID'))
except UnboundLocalError: except UnboundLocalError:
@ -88,6 +101,21 @@ def identifyUserType(obj):
return "User" return "User"
else: else:
return None return None
def parseHomefolder(user, virtualfolder):
"""Extract users home folder using the username. Will not work on edge cases
such as when a users home folder does not have the user name. When that occurs
it is impossible to know based on the arm data what the home folder is.
This function is an assumption so it may return the incorrect home folder.
This function finds the user name and takes the path from the left of the folder
as the home folder. There are cases where this may not be accurate."""
if user:
userSplit = f'/{user}/'
if virtualfolder:
if userSplit in virtualfolder:
home = virtualfolder.split(userSplit)[0] + userSplit
return home if home else None
def identifyUtype(obj): def identifyUtype(obj):
"""Process Type of transaction based on string that passed in. """Process Type of transaction based on string that passed in.
Return transaction type.""" Return transaction type."""
@ -98,11 +126,11 @@ def identifyUtype(obj):
if obj in user_logged_on: if obj in user_logged_on:
return "user_logged_on" return "user_logged_on"
if obj in file_deleted: elif obj in file_deleted:
return "file_deleted" return "file_deleted"
if obj in file_uploaded: elif obj in file_uploaded:
return "file_uploaded" return "file_uploaded"
if obj in file_downloaded: elif obj in file_downloaded:
return "file_downloaded" return "file_downloaded"
else: else:
return "other" return "other"

View File

@ -1,9 +1,9 @@
class sqlQuerymodel: class sqlQuerymodel:
def queryData(overRideflag, configQuery, daysTopull): def queryData(overRideflag, configQuery, daysTopull):
"""Embedded query data""" """Embedded query data. Data is slightly modified to change the amount of days to pull."""
q ="""DECLARE @stopTime DATETIME2 q ="""DECLARE @stopTime DATETIME2
SET @stopTime=DATEADD(DAY, -30, GETDATE()) SET @stopTime=DATEADD(DAY, -30, GETDATE())
SELECT p.ProtocolCommandID, t.Time_stamp, p.RemoteIP, p.RemotePort, p.LocalIP, p.LocalPort, p.Protocol, p.SiteName, p.Command, p.FileName, p.VirtualFolderName, p.FileSize, p.TransferTime, p.BytesTransferred, p.Description, p.ResultID, t.TransactionID, p.Actor, t.TransactionObject, t.NodeName, t.TransactionGUID, a.Protocol user_type SELECT p.ProtocolCommandID, t.Time_stamp, p.RemoteIP, p.RemotePort, p.LocalIP, p.LocalPort, p.Protocol, p.SiteName, p.Command, p.FileName, p.PhysicalFolderName, p.VirtualFolderName, p.FileSize, p.TransferTime, p.BytesTransferred, p.Description, p.ResultID, t.TransactionID, p.Actor, t.TransactionObject, t.NodeName, t.TransactionGUID, a.Protocol user_type
FROM tbl_Transactions t FROM tbl_Transactions t
Full JOIN tbl_ProtocolCommands p ON(t.TransactionID=p.TransactionID) Full JOIN tbl_ProtocolCommands p ON(t.TransactionID=p.TransactionID)
Full join tbl_Authentications a ON(t.TransactionID=a.TransactionID) Full join tbl_Authentications a ON(t.TransactionID=a.TransactionID)

14
test.py
View File

@ -15,8 +15,6 @@ def builddict(keys,*args,**kwargs):
dict[key] = kwargs.get(key) dict[key] = kwargs.get(key)
print(dict) print(dict)
testfolder = '/Usr/a/asdf/asf'
user = 'a'
def identifyUtype(obj): def identifyUtype(obj):
"""Process Type of transaction based on string that passed in. """Process Type of transaction based on string that passed in.
@ -36,3 +34,15 @@ def identifyUtype(obj):
return "file_downloaded" return "file_downloaded"
else: else:
return "other" return "other"
testfolder = '/Usr/a/asdf/asf/asdfas/asdfasdf/'
user = 'a'
def parsehomefolder(user, virtualfolder):
userSplit = f'/{user}/'
home = virtualfolder.split(userSplit)[0] + userSplit
print(home)
return home
a = parsehomefolder(user, testfolder)