Skip to content

Commit

Permalink
Merge pull request #33 from splunk-soar-connectors/SOARHELP-4116_exte…
Browse files Browse the repository at this point in the history
…nded_logging

Extended logging around connecting to the server
  • Loading branch information
bb-splunk authored Dec 23, 2024
2 parents c02cece + 7edaaf6 commit 91b6179
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/phantomcyber/dev-cicd-tools
rev: v1.19
rev: v1.24
hooks:
- id: org-hook
- id: package-app-dependencies
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Connector Version: 3.3.0
Product Vendor: Generic
Product Name: SMTP
Product Version Supported (regex): ".\*"
Minimum Product Version: 6.2.1
Minimum Product Version: 6.3.0

This app provides the ability to send email using SMTP

Expand Down Expand Up @@ -257,15 +257,14 @@ This app provides the ability to send email using SMTP
Recipients Test\\n\\nThis is test data.


### Configuration Variables
The below configuration variables are required for this Connector to operate. These variables are specified when configuring a SMTP asset in SOAR.
### Configuration variables
This table lists the configuration variables required to operate SMTP. These variables are specified when configuring a SMTP asset in Splunk SOAR.

VARIABLE | REQUIRED | TYPE | DESCRIPTION
-------- | -------- | ---- | -----------
**server** | required | string | Server IP/Hostname
**port** | optional | numeric | Port
**auth_type** | optional | string | Authentication type to use for connectivity
**ph_0** | optional | ph | Place holder
**username** | optional | string | Username (or email address)
**password** | optional | password | Password (For Basic Auth)
**client_id** | optional | string | OAuth Client ID (For OAuth)
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ verbose = true

[tool.isort]
line_length = 145
profile = "black"
1 change: 1 addition & 0 deletions release_notes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
**Unreleased**
* Extended logging [SOARHELP-4116]
2 changes: 1 addition & 1 deletion smtp.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"product_vendor": "Generic",
"product_name": "SMTP",
"product_version_regex": ".*",
"min_phantom_version": "6.2.1",
"min_phantom_version": "6.3.0",
"rest_handler": "request_handler.handle_request",
"license": "Copyright (c) 2016-2024 Splunk Inc.",
"logo": "logo_splunk.svg",
Expand Down
36 changes: 21 additions & 15 deletions smtp_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def _with_oauth_type(self, action_result):
return self.set_status(phantom.APP_ERROR, SMTP_DECRYPTION_ERROR)

if phantom.is_fail(self._connect_to_server_helper(action_result)):
self.debug_print("OAuth authentication failed")
return action_result.get_status()

return phantom.APP_SUCCESS
Expand Down Expand Up @@ -173,29 +174,28 @@ def _process_auth_type(self, action_result):
if auth_type == SMTP_PASSWORD_LESS_AUTH_TYPE:
if action_id != SMTP_TEST_CONNECTIVITY:
msg = "Authentication failed for connecting to server with {} types \
of authentication.{}".format(
SMTP_ALLOWED_AUTH_TYPES[1:], SMTP_FAILED_CONNECTIVITY_TEST
of authentication. Message: {}.{}".format(
SMTP_ALLOWED_AUTH_TYPES[1:], msg, SMTP_FAILED_CONNECTIVITY_TEST
)
return action_result.set_status(phantom.APP_ERROR, msg)
else:
return action_result.set_status(phantom.APP_ERROR)
return action_result.set_status(phantom.APP_ERROR)
else:
return phantom.APP_SUCCESS

# Check specific auth type as per input given by user in auth_type parameter
self.save_progress(SMTP_AUTH_MESSAGE.format(auth_type)) # nosemgrep
auth = eval(f"self._with_{auth_type.lower()}_type(action_result)")
if phantom.is_fail(auth):
self.debug_print(f"Authentication failed using {auth_type}")
msg = action_result.get_message()
if action_id != SMTP_TEST_CONNECTIVITY:
msg = "Authentication failed for connecting to server with {} \
authentication.{}".format(
auth_type, SMTP_FAILED_CONNECTIVITY_TEST
msg = "Authentication failed for connecting to server with {} authentication. Message: {}.{}".format(
auth_type, msg, SMTP_FAILED_CONNECTIVITY_TEST
)
return action_result.set_status(phantom.APP_ERROR, msg)
else:
return action_result.set_status(phantom.APP_ERROR, msg)
return action_result.set_status(phantom.APP_ERROR, msg)

self.debug_print(f"Authentication succeeded using {auth_type}")
return phantom.APP_SUCCESS

def finalize(self):
Expand All @@ -211,7 +211,7 @@ def finalize(self):
self._state["oauth_token"]["refresh_token"] = self._refresh_token
self._state[SMTP_STATE_IS_ENCRYPTED] = True
except Exception as e:
self.debug_print("{}: {}".format(SMTP_ENCRYPTION_ERROR, self._get_error_message_from_exception(e)))
self.error_print("{}: {}".format(SMTP_ENCRYPTION_ERROR, self._get_error_message_from_exception(e)))
return self.set_status(phantom.APP_ERROR, SMTP_ENCRYPTION_ERROR)

self.save_state(self._state)
Expand Down Expand Up @@ -388,7 +388,7 @@ def _interactive_auth_initial(self, client_id, rsh, client_secret):
return phantom.APP_SUCCESS, ""

def _interactive_auth_refresh(self):

self.debug_print("Attempting to refresh OAuth token")
config = self.get_config()
client_id = config.get("client_id")
client_secret = config.get("client_secret")
Expand Down Expand Up @@ -426,10 +426,11 @@ def _interactive_auth_refresh(self):
self._refresh_token = oauth_token.get("refresh_token")

self._state["oauth_token"] = oauth_token
self.debug_print("OAuth token refresh succeeded")
return phantom.APP_SUCCESS, ""

def _set_interactive_auth(self, action_result):

self.debug_print("Setting interactive auth")
config = self.get_config()
client_id = config.get("client_id")
client_secret = config.get("client_secret")
Expand Down Expand Up @@ -551,7 +552,6 @@ def handle_exception(self, e):
self._cleanup()

def _connect_to_server(self, action_result, first_try=True):

config = self.get_config()
is_oauth = self._auth_mechanism == SMTP_OAUTH_AUTH_TYPE

Expand Down Expand Up @@ -590,11 +590,12 @@ def _connect_to_server(self, action_result, first_try=True):
self._smtp_conn.ehlo()
# Login
try:
self.debug_print("Attempting to login")
if self._auth_mechanism == SMTP_OAUTH_AUTH_TYPE:
if config.get(phantom.APP_JSON_USERNAME) is None:
return action_result.set_status(
phantom.APP_ERROR,
"A username must be specified to run test connectivity using OAuth. " "Please check your asset configuration.",
"A username must be specified to run test connectivity using OAuth. Please check your asset configuration.",
)
auth_string = self._generate_oauth_string(config[phantom.APP_JSON_USERNAME], self._access_token)
# self._smtp_conn.ehlo(config.get("client_id"))
Expand All @@ -605,8 +606,12 @@ def _connect_to_server(self, action_result, first_try=True):
elif self._auth_mechanism == SMTP_PASSWORD_LESS_AUTH_TYPE:
self.debug_print(SMTP_MESSAGE_SKIP_AUTH_NO_USERNAME_PASSWORD)
response_code, response_message = (None, None)
else:
self.debug_print(f"Unsupported auth_mechanism: {self._auth_mechanism}")
return action_result.set_status(phantom.APP_ERROR, "Login failed due to an unsupported auth mechanism. This shouldn't happen.")

except Exception as e:
self.debug_print(f"Exception occurred while attempting to login using OAuth. Details: {e}")
# If token is expired, use the refresh token to re-new the access token
error_text = self._get_error_message_from_exception(e)
if first_try and is_oauth and "Invalid credentials" in error_text:
Expand All @@ -618,6 +623,7 @@ def _connect_to_server(self, action_result, first_try=True):
raise e

if response_code is not None:
self.debug_print(f"Response to login attempt received. Response code: {response_code}")
# 334 status code for smtp signifies that the requested security mechanism is accepted
if response_code == 334:
decoded_bytes = base64.b64decode(response_message)
Expand Down Expand Up @@ -939,7 +945,7 @@ def _generate_oauth_string(self, username, access_token):

def _connect_to_server_helper(self, action_result):
"""Redirect the flow based on auth type"""

self.debug_print("Connecting to SMTP server")
if self._auth_mechanism == SMTP_OAUTH_AUTH_TYPE:
if self._refresh_token and self._access_token == "":
self.debug_print("Try to generate token from refresh token")
Expand Down
5 changes: 1 addition & 4 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
[flake8]
max-line-length = 145
max-complexity = 28
extend-ignore = F403,E128,E126,E121,E127,E731,E201,E202,F405,E722,D

[isort]
line_length = 145
extend-ignore = F403,E128,E126,E121,E127,E731,E201,E202,E203,E701,F405,E722,D,W503

0 comments on commit 91b6179

Please sign in to comment.