Skip to content

Commit

Permalink
support for kerberos and certificate
Browse files Browse the repository at this point in the history
  • Loading branch information
mposluszny-splunk committed Jan 15, 2024
1 parent e3393d5 commit 0865953
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 14 deletions.
22 changes: 21 additions & 1 deletion winrm.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,30 @@
"required": true,
"value_list": [
"basic",
"ntlm"
"ntlm",
"certificate",
"kerberos"
],
"default": "basic",
"order": 7
},
"cert_pem_path": {
"description": "Path to SSL certificate PEM file",
"data_type": "string",
"required": false,
"order": 8
},
"cert_key_pem_path": {
"description": "Path to SSL key file",
"data_type": "string",
"required": false,
"order": 9
},
"ca_trust_path": {
"description": "Path to trusted CRT file",
"data_type": "string",
"required": false,
"order": 10
}
},
"actions": [
Expand Down
52 changes: 39 additions & 13 deletions winrm_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,19 @@ def _sanitize_string(self, string):
# The breaking character in PS is '`', so first we break any breaking characters, then we
# break any double quotes which are found, then we break any $, which is used to declare variables
return string.replace('`', '``').replace('"', '`"').replace('$', '`$').replace('&', '`&').replace(')', '`)').replace('(', '`(')

def _get_fips_enabled(self):
try:
from phantom_common.install_info import is_fips_enabled
except ImportError:
return False

fips_enabled = is_fips_enabled()
if fips_enabled:
self.debug_print('FIPS is enabled')
else:
self.debug_print('FIPS is not enabled')
return fips_enabled

def _create_ps_script(self, action_result, args, whitelist_args=set(), cmd_prefix="", cmd_suffix=""):
# Here, you can pass it something like {"val1": "value"} which will generate a string for "-val1 value"
Expand Down Expand Up @@ -224,19 +237,19 @@ def _create_ps_script(self, action_result, args, whitelist_args=set(), cmd_prefi
def _init_session(self, action_result, param=None):
config = self.get_config()

default_protocol = config.get('default_protocol', 'http')
default_protocol = config.get(consts.WINRM_CONFIG_PROTOCOL, 'http')
ret_val, default_port = self._validate_integer(
action_result,
config.get('default_port', 5985 if default_protocol == 'http' else 5986),
config.get(consts.WINRM_CONFIG_PORT, 5985 if default_protocol == 'http' else 5986),
"Default port",
True)
if phantom.is_fail(ret_val):
return action_result.get_status()

endpoint = self._handle_py_ver_compat_for_input_str(config.get(consts.WINRM_CONFIG_ENDPOINT))
if param:
endpoint = self._handle_py_ver_compat_for_input_str(param.get('ip_hostname', config.get('endpoint')))
else:
endpoint = self._handle_py_ver_compat_for_input_str(config.get('endpoint'))
endpoint = self._handle_py_ver_compat_for_input_str(param.get('ip_hostname', endpoint))

if endpoint is None:
return action_result.set_status(
phantom.APP_ERROR, "No Endpoint Configured"
Expand All @@ -245,12 +258,16 @@ def _init_session(self, action_result, param=None):
endpoint = '{0}://{1}'.format(default_protocol, endpoint)
if re.search(r':\d+$', endpoint, re.UNICODE | re.IGNORECASE) is None:
endpoint = '{0}:{1}'.format(endpoint, default_port)
username = config['username']
password = config['password']
transport = config.get('transport')
domain = self._handle_py_ver_compat_for_input_str(config.get('domain'))
username = config[consts.WINRM_CONFIG_USERNAME]
password = config[consts.WINRM_CONFIG_PASSWORD]
transport = config.get(consts.WINRM_CONFIG_TRANSPORT)
domain = self._handle_py_ver_compat_for_input_str(config.get(consts.WINRM_CONFIG_DOMAIN))

verify_bool = config.get(phantom.APP_JSON_VERIFY, False)
cert_pem_path = None
cert_key_pem_path = None
cert_ca_trust_path = config.get(consts.WINRM_CONFIG_CA_TRUST, "legacy_requests")

if verify_bool:
verify = 'validate'
else:
Expand All @@ -262,12 +279,18 @@ def _init_session(self, action_result, param=None):
"Warning: Domain is set but transport type is set to 'basic'"
)
elif transport == 'ntlm':
if self._get_fips_enabled():
return action_result.set_status(
phantom.APP_ERROR, "This transport type is not supported when FIPS is enabled"
)
if domain:
username = r'{}\{}'.format(domain, username)
elif transport == 'kerberos':
return action_result.set_status(
phantom.APP_ERROR, "This transport type is not yet implemented"
)
username = r'{}\{}'.format(domain, username)
elif transport == 'certificate':
username = r'{}\{}'.format(domain, username)
cert_pem_path = config.get(consts.WINRM_CONFIG_CERT_PEM)
cert_key_pem_path = config.get(consts.WINRM_CONFIG_CERT_KEY_PEM)
elif transport == 'credssp':
return action_result.set_status(
phantom.APP_ERROR, "This transport type is not yet implemented"
Expand All @@ -281,7 +304,10 @@ def _init_session(self, action_result, param=None):
endpoint,
auth=(username, password),
server_cert_validation=verify,
transport=transport
transport=transport,
cert_pem=cert_pem_path,
cert_key_pem=cert_key_pem_path,
ca_trust_path=cert_ca_trust_path
)
self._protocol = self._session.protocol

Expand Down
13 changes: 13 additions & 0 deletions winrm_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,16 @@
LOCATION_VALUE_LIST = ["local", "domain", "effective"]
DENY_ALLOW_VALUE_LIST = ["deny", "allow"]
VALUE_LIST_VALIDATION_MESSAGE = "Please provide valid input from {} in '{}' action parameter"

# Config keys

WINRM_CONFIG_ENDPOINT = "endpoint"
WINRM_CONFIG_PROTOCOL = "default_protocol"
WINRM_CONFIG_PORT = "default_port"
WINRM_CONFIG_USERNAME = "username"
WINRM_CONFIG_PASSWORD = "password"
WINRM_CONFIG_TRANSPORT = "transport"
WINRM_CONFIG_DOMAIN = "domain"
WINRM_CONFIG_CERT_PEM = "cert_pem_path"
WINRM_CONFIG_CERT_KEY_PEM = "cert_key_pem_path"
WINRM_CONFIG_CA_TRUST = "ca_trust_path"

0 comments on commit 0865953

Please sign in to comment.