1
1
# File: ciscotalosintelligence_connector.py
2
2
#
3
- # Copyright (c) 2024 Splunk Inc.
3
+ # Copyright (c) 2025 Splunk Inc.
4
4
#
5
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
6
# you may not use this file except in compliance with the License.
@@ -47,7 +47,6 @@ def __new__(cls, val1, val2=None):
47
47
48
48
49
49
class TalosIntelligenceConnector (BaseConnector ):
50
-
51
50
def __init__ (self ):
52
51
super (TalosIntelligenceConnector , self ).__init__ ()
53
52
@@ -64,7 +63,10 @@ def _process_empty_response(self, response, action_result):
64
63
if response .status_code == 200 :
65
64
return RetVal (phantom .APP_SUCCESS , {})
66
65
67
- return RetVal (action_result .set_status (phantom .APP_ERROR , "Empty response and no information in the header" ), None )
66
+ return RetVal (
67
+ action_result .set_status (phantom .APP_ERROR , "Empty response and no information in the header" ),
68
+ None ,
69
+ )
68
70
69
71
def _process_html_response (self , response , action_result ):
70
72
# An html response, treat it like an error
@@ -89,7 +91,13 @@ def _process_json_response(self, r, action_result):
89
91
try :
90
92
resp_json = r .json ()
91
93
except Exception as e :
92
- return RetVal (action_result .set_status (phantom .APP_ERROR , "Unable to parse JSON response. Error: {0}" .format (str (e ))), None )
94
+ return RetVal (
95
+ action_result .set_status (
96
+ phantom .APP_ERROR ,
97
+ "Unable to parse JSON response. Error: {0}" .format (str (e )),
98
+ ),
99
+ None ,
100
+ )
93
101
94
102
# Please specify the status codes here
95
103
if 200 <= r .status_code < 399 :
@@ -114,13 +122,20 @@ def _process_response(self, r, action_result, retry=3):
114
122
err_msg = r .headers .get ("grpc-message" , "Error" )
115
123
return (
116
124
action_result .set_status (
117
- phantom .APP_ERROR , f"Got retryable grpc-status of { r .headers ['grpc-status' ]} with message { err_msg } "
125
+ phantom .APP_ERROR ,
126
+ f"Got retryable grpc-status of { r .headers ['grpc-status' ]} with message { err_msg } " ,
118
127
),
119
128
r ,
120
129
)
121
130
122
131
if r .status_code == 503 :
123
- return action_result .set_status (phantom .APP_ERROR , "Got retryable http status code {0}" .format (r .status_code )), r
132
+ return (
133
+ action_result .set_status (
134
+ phantom .APP_ERROR ,
135
+ "Got retryable http status code {0}" .format (r .status_code ),
136
+ ),
137
+ r ,
138
+ )
124
139
125
140
# Process each 'Content-Type' of response separately
126
141
@@ -171,20 +186,32 @@ def _make_rest_call(self, retry, endpoint, action_result, method="get", **kwargs
171
186
172
187
with tempfile .NamedTemporaryFile (mode = "w+" , delete = False , suffix = "test" ) as temp_file :
173
188
cert_string = f"-----BEGIN CERTIFICATE-----\n { self ._cert } \n -----END CERTIFICATE-----"
174
- cert = f"{ cert_string } \n -----BEGIN RSA PRIVATE KEY-----\n { self ._key } \n -----END RSA PRIVATE KEY-----\n "
189
+ cert = (
190
+ f"{ cert_string } \n "
191
+ "-----BEGIN RSA PRIVATE KEY-----\n " # pragma: allowlist secret
192
+ f"{ self ._key } \n "
193
+ "-----END RSA PRIVATE KEY-----\n " # pragma: allowlist secret
194
+ )
175
195
temp_file .write (cert )
176
196
temp_file .seek (0 ) # Move the file pointer to the beginning for reading
177
197
temp_file_path = temp_file .name # Get the name of the temporary file
178
198
self .client = httpx .Client (
179
- http2 = True , verify = config .get ("verify_server_cert" , False ), cert = temp_file_path , timeout = MAX_REQUEST_TIMEOUT
199
+ http2 = True ,
200
+ verify = config .get ("verify_server_cert" , False ),
201
+ cert = temp_file_path ,
202
+ timeout = MAX_REQUEST_TIMEOUT ,
180
203
)
181
204
182
205
if os .path .exists (temp_file_path ):
183
206
os .remove (temp_file_path )
184
207
185
208
if i == MAX_CONNECTION_RETIRIES - 1 :
186
209
return RetVal (
187
- action_result .set_status (phantom .APP_ERROR , "Error Connecting to server. Details: {0}" .format (str (e ))), resp_json
210
+ action_result .set_status (
211
+ phantom .APP_ERROR ,
212
+ "Error Connecting to server. Details: {0}" .format (str (e )),
213
+ ),
214
+ resp_json ,
188
215
)
189
216
190
217
return self ._process_response (r , action_result , retry )
@@ -195,7 +222,13 @@ def _make_rest_call_helper(self, *args, **kwargs):
195
222
for i in range (MAX_REQUEST_RETRIES + 1 ):
196
223
if time .time () > max_processing_time :
197
224
action_result = args [1 ]
198
- return action_result .set_status (phantom .APP_ERROR , f"Max request timeout of { MAX_REQUEST_TIMEOUT } s exceeded" ), None
225
+ return (
226
+ action_result .set_status (
227
+ phantom .APP_ERROR ,
228
+ f"Max request timeout of { MAX_REQUEST_TIMEOUT } s exceeded" ,
229
+ ),
230
+ None ,
231
+ )
199
232
200
233
ret_val , response = self ._make_rest_call (i , * args , ** kwargs )
201
234
if phantom .is_fail (ret_val ) and response :
@@ -313,7 +346,6 @@ def _handle_url_reputation(self, param):
313
346
return action_result .set_status (phantom .APP_SUCCESS )
314
347
315
348
def _query_reputation (self , action_result , payload , observable = None ):
316
-
317
349
taxonomy_ret_val , taxonomy = self ._fetch_taxonomy (action_result )
318
350
319
351
if phantom .is_fail (taxonomy_ret_val ):
@@ -368,7 +400,6 @@ def _query_reputation(self, action_result, payload, observable=None):
368
400
return phantom .APP_SUCCESS
369
401
370
402
def _fetch_taxonomy (self , action_result , allow_cache = True ):
371
-
372
403
payload = {"app_info" : self ._appinfo }
373
404
374
405
if "taxonomy" in self ._state and allow_cache :
@@ -473,7 +504,12 @@ def insert_newlines(string, every=64):
473
504
self ._appinfo ["perf_testing" ] = True
474
505
475
506
with tempfile .NamedTemporaryFile (mode = "w+" , delete = False , suffix = "test" ) as temp_file :
476
- cert = f"{ cert_string } \n -----BEGIN RSA PRIVATE KEY-----\n { textwrap .fill (self ._key , 64 )} \n -----END RSA PRIVATE KEY-----\n "
507
+ cert = (
508
+ f"{ cert_string } \n "
509
+ "-----BEGIN RSA PRIVATE KEY-----\n " # pragma: allowlist secret
510
+ f"{ textwrap .fill (self ._key , 64 )} \n "
511
+ "-----END RSA PRIVATE KEY-----\n " # pragma: allowlist secret
512
+ )
477
513
478
514
temp_file .write (cert )
479
515
temp_file .seek (0 ) # Move the file pointer to the beginning for reading
@@ -482,7 +518,10 @@ def insert_newlines(string, every=64):
482
518
# exceptions shouldn't really be thrown here because most network related disconnections will happen when a request is sent
483
519
try :
484
520
self .client = httpx .Client (
485
- http2 = True , verify = config .get ("verify_server_cert" , False ), cert = temp_file_path , timeout = MAX_REQUEST_TIMEOUT
521
+ http2 = True ,
522
+ verify = config .get ("verify_server_cert" , False ),
523
+ cert = temp_file_path ,
524
+ timeout = MAX_REQUEST_TIMEOUT ,
486
525
)
487
526
except Exception as e :
488
527
self .debug_print (f"Could not connect to server because of { e } " )
@@ -515,7 +554,6 @@ def main():
515
554
password = args .password
516
555
517
556
if username is not None and password is None :
518
-
519
557
# User specified a username but not a password, so ask
520
558
import getpass
521
559
0 commit comments