diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d05562a..391d3a5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 diff --git a/README.md b/README.md index b49d64e..01e93ba 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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) diff --git a/pyproject.toml b/pyproject.toml index 474efd9..4c594fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,3 +5,4 @@ verbose = true [tool.isort] line_length = 145 +profile = "black" diff --git a/release_notes/unreleased.md b/release_notes/unreleased.md index fbcb2fd..8f52505 100644 --- a/release_notes/unreleased.md +++ b/release_notes/unreleased.md @@ -1 +1,2 @@ **Unreleased** +* Extended logging [SOARHELP-4116] \ No newline at end of file diff --git a/smtp.json b/smtp.json index c52ff41..9fc9a7f 100644 --- a/smtp.json +++ b/smtp.json @@ -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", diff --git a/smtp_connector.py b/smtp_connector.py index 28b8610..38046a1 100644 --- a/smtp_connector.py +++ b/smtp_connector.py @@ -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 @@ -173,12 +174,11 @@ 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 @@ -186,16 +186,16 @@ def _process_auth_type(self, action_result): 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): @@ -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) @@ -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") @@ -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") @@ -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 @@ -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")) @@ -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: @@ -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) @@ -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") diff --git a/tox.ini b/tox.ini index 04a3cec..720a141 100644 --- a/tox.ini +++ b/tox.ini @@ -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