From 11b2d255b6a95c6477578be660404324c6cfd4af Mon Sep 17 00:00:00 2001 From: = <=> Date: Tue, 9 Sep 2025 16:57:30 -0400 Subject: [PATCH] Working on Pulling info about client --- AirlockTools.py | 15 ++++++---- parquet/newOTP | Bin 0 -> 374 bytes parquet/newest_active_OTP | Bin 0 -> 374 bytes parquet/old_active_OTP | Bin 0 -> 374 bytes parquet/otp_activities | Bin 0 -> 2470 bytes utils/clientfunctions.py | 60 ++++++++++++++++++++++++++++++++++++++ utils/otpfunctions.py | 58 +++++++++++++++++++++++++++++++----- 7 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 parquet/newOTP create mode 100644 parquet/newest_active_OTP create mode 100644 parquet/old_active_OTP create mode 100644 parquet/otp_activities create mode 100644 utils/clientfunctions.py diff --git a/AirlockTools.py b/AirlockTools.py index 8e115c2..2615096 100644 --- a/AirlockTools.py +++ b/AirlockTools.py @@ -16,8 +16,10 @@ import argparse import dotenv import os import pandas as pd + import urllib3 import utils.allowlist +import utils.clientfunctions import utils.getdeviceevents import utils.hashfunctions import utils.otpfunctions @@ -26,6 +28,7 @@ import utils.policyfunctions import utils.pretty as ct + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) dotenv.load_dotenv() @@ -48,15 +51,15 @@ def main(): args = parser.parse_args() if args.monitorOTP: - # Non-interactive logic + + + # Non-interactive logic + if not os.path.exists("parquet"): os.makedirs("parquet") apivalidation() print(f"Running non-interactively to start monitoring OTP") - - utils.otpfunctions.getOTPHistory(url, 0) - utils.otpfunctions.getOTPHistory(url, 1) - utils.otpfunctions.getOTPHistory(url, 2) - utils.otpfunctions.getOTPHistory(url, 3) + utils.clientfunctions.getClientsPolicy(url) + # Process input here else: # Interactive logic diff --git a/parquet/newOTP b/parquet/newOTP new file mode 100644 index 0000000000000000000000000000000000000000..f80e99c665fac554d8b1536ba4d1d15a5e9e2152 GIT binary patch literal 374 zcmZ9I%}&EG5QI$+eS@Mz>cR2}Bx)t4;=qj?$BHXL(YD@FBik|lL5-rk2ak)BRQ=(& zJDzW5y?%KsXOn#XI`!K3hp|5|yY7 zXiT$-Nn?X^6hSR@rc(Xs9$y%-A&$;0Rn zLhTZyWlC-wxTXj0zy}NNJ7VauKj^%yO|LAA<%*XjFIbm^;g0Gb^H}22#2cR2}Bx)t4;=qj?$BHXL(YD@FBik|lL5-rk2ak)BRQ=(& zJDzW5y?%KsXOn#XI`!K3hp|5|yY7 zXiT$-Nn?X^6hSR@rc(Xs9$y%-A&$;0Rn zLhTZyWlC-wxTXj0zy}NNJ7VauKj^%yO|LAA<%*XjFIbm^;g0Gb^H}22#2cR2}Bx)t4;=qj?$BHXL(YD@FBik|lL5-rk2ak)BRQ=(& zJDzW5y?%KsXOn#XI`!K3hp|5|yY7 zXiT$-Nn?X^6hSR@rc(Xs9$y%-A&$;0Rn zLhTZyWlC-wxTXj0zy}NNJ7VauKj^%yO|LAA<%*XjFIbm^;g0Gb^H}22#2Vf&g|~UUU#+H z?yij8Bw%_drIb)|%pr#oddQ)Np7S3xryL5s^iWDqrMNAW9)jtt)`}$4nu6&bjOV@g zz3+Q(-dpYJl^aL^!i&7{d~8-I@qY_K5rD(&!SyTvpp;qQf3Mb?>k$j1X4~~V7H)U8 znpc8gp2oDf+_9C&#DU2ZPX z9opOu8IlbdZm0+~J=bc6vAj*gZ~g#NH{V=;r*Z2E0C4FEnAm?s3c?-NW?axb^VlYh zJE6>W8Lz7M@PeOb1b?V>cR4M5ocmWgv9#uH`po%Z5(LxSvKBBqW}$RFh-Rfl-CJLds{Y8~p+;`!TC1lARGS_C)`uc-}$6BpKR9f?TpkgNFV ze^Y^!fr|5D!$``33fEglcv!?;;r37?UVk<11IX4vJ~L6w?d9^5Q{dO{-yO@3Pl$8k zZ;5~K2-(WrYlX<(Vr?pvfKa-S6^kvtVm@uN3w%-&!`Yx~d2Y1D!oH;tZBd12{o}YD zG8(hk9bnG1J5K+c6ZSL0QQpY?h=FpcGE?y`7H5P~MF5onqmV6^%3l`Be~nc@xj3f* zP?_P42126x;(o3V7%1u?{>+pgWH@3!cO3E{--jGY?#2IJD8I<@_y_sp@%P93@k2HB zFh6F?pJzGd{`hgs!%`p9FS-x-ECD<$9S1y~oDp(^!jqQt5RWqDkCQSUPtJ+O~}qHR;spH%r`Km1Iwu2@3w=zjd(9eFx8H=&0l0yj!UUtI@<0ob84<1vrQIO@4e3> zQU(7+&4r|6l_dIC0V7fWQAXEy?T*8$_hzMIw1m^FN1IM0Ic#aw7&sidx35M literal 0 HcmV?d00001 diff --git a/utils/clientfunctions.py b/utils/clientfunctions.py new file mode 100644 index 0000000..32c009c --- /dev/null +++ b/utils/clientfunctions.py @@ -0,0 +1,60 @@ +import json +import requests +import os +import pandas as pd +import utils.pretty as ct + + +def getClientsPolicy(url, clientid="0dcddaf3-d017-4ced-9227-ceeca3117286"): + + endpoint = url + '/v1/agent/find' + payload = { + "agentid" : f"{clientid}" + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + data = pd.DataFrame(result["response"]["agents"]) + + policyname = getPolicyName(url,data.loc[0, "groupid"]) + allowlists = getPolicyAllowlists(url,data.loc[0, "groupid"]) + allowlists = allowlists['name'].tolist() + print(policyname) + print(allowlists) + + + +def getPolicyAllowlists(url, groupid): + + endpoint = url + '/v1/group/policies' + payload = { + "groupid" : f"{groupid}" + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + data = pd.DataFrame(result["response"]["applications"]) + return data + +def getPolicyName(url, groupid): + + endpoint = url + '/v1/group/' + payload = { + + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + data = pd.DataFrame(result["response"]["groups"]) + name = data.loc[data['groupid'] == f"{groupid}", 'name'].values[0] + return name \ No newline at end of file diff --git a/utils/otpfunctions.py b/utils/otpfunctions.py index 509aa96..ab1c05a 100644 --- a/utils/otpfunctions.py +++ b/utils/otpfunctions.py @@ -1,21 +1,63 @@ import json import requests import os +import pandas as pd +import utils.pretty as ct +import shutil +def getActiveOTP(url): -def getOTPHistory(url, type): - - endpoint = url + '/v1/otp/usage' + endpoint = url + f'/v1/otp/usage' payload = { - "status" : type - } + "status" : "0" + } headers = {"X-APIKey": os.getenv('APIKEY')} payload = json.dumps(payload) response = requests.post(endpoint, headers=headers, data=payload, verify=False) - data = response.json() - results = data.get("response", {}).get("otpusage", []) + result = json.loads(response.text) + otp = pd.DataFrame(result["response"]["otpusage"]) + otp.to_parquet("parquet\\newest_active_OTP.parquet", index=False) + if not otp.empty: + ct.style_dataframe_dark(otp, f"newest_active_OTP.html") + - print(results) \ No newline at end of file + +def getOTPActivities(url, otpid): + + endpoint = url + f'/v1/otp/activities' + payload = { + "otpid" : f"{otpid}" + } + + headers = {"X-APIKey": os.getenv('APIKEY')} + payload = json.dumps(payload) + + response = requests.post(endpoint, headers=headers, data=payload, verify=False) + result = json.loads(response.text) + otp = pd.DataFrame(result["response"]["otpactivities"]) + otp.to_parquet("parquet/otp_activities.parquet", index=False) + if not otp.empty: + ct.style_dataframe_dark(otp, f"OTP_activities_{otpid}.html") + + +def compareOTPHistory(): + + if not os.path.exists("parquet\\old_active_OTP"): + shutil.copy2("parquet\\newest_active_OTP.parquet", "parquet\\old_active_OTP.parquet") + + old_active_OTP = pd.read_parquet("parquet\\old_active_OTP.parquet") + current_active_OTP = pd.read_parquet("parquet\\newest_active_OTP.parquet") + + newly_added = current_active_OTP[~current_active_OTP['otpid'].isin(old_active_OTP['otpid'])] + still_in_OTP = old_active_OTP[old_active_OTP['otpid'].isin(current_active_OTP['otpid'])] + no_longer_OTP = old_active_OTP[~old_active_OTP['otpid'].isin(current_active_OTP['otpid'])] + + + + for _, row in newly_added.iterrows(): + pid = row['otpid'] + # Access other columns via row['column_name'] + print(f"Processing PID: {pid} with other data: {row}")