def feed_main(feed_name, params=None, prefix=''):
    if not params:
        params = {k: v for k, v in demisto.params().items() if v is not None}
    handle_proxy()
    client = Client(**params)
    command = demisto.command()
    if command != 'fetch-indicators':
        demisto.info('Command being called is {}'.format(command))
    if prefix and not prefix.endswith('-'):
        prefix += '-'
    # Switch case
    commands: dict = {
        'test-module': module_test_command,
        f'{prefix}get-indicators': get_indicators_command
    }
    try:
        if command == 'fetch-indicators':
            indicators = fetch_indicators_command(client,
                                                  params.get('indicator_type'))
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)  # type: ignore
        else:
            args = demisto.args()
            args['feed_name'] = feed_name
            readable_output, outputs, raw_response = commands[command](client,
                                                                       args)
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        err_msg = f'Error in {feed_name} Integration - Encountered an issue with createIndicators' if \
            'failed to create' in str(e) else f'Error in {feed_name} Integration [{e}]'
        return_error(err_msg)
Exemple #2
0
def main():
    global EMAIL

    command = demisto.command()
    client = Client()
    demisto.info(f'Command being called is {command}')

    commands = {
        'test-module': test_module,
        'send-mail': send_mail_command,
        'fetch-incidents': fetch_incidents,
        'gmail-auth-link': auth_link_command,
        'gmail-auth-test': auth_test_command,
    }

    try:
        if command == 'fetch-incidents':
            demisto.incidents(fetch_incidents(client))
            sys.exit(0)
        if command in commands:
            demisto.results(commands[command](client))
        # Log exceptions
    except Exception as e:
        import traceback
        return_error('GMAIL: {}'.format(str(e)), traceback.format_exc())
def main():
    max_indicators = get_limit(demisto.params().get('maxIndicators', MAX_INDICATORS), MAX_INDICATORS)

    SESSION.proxies = handle_proxy()

    client = SixgillFeedClient(demisto.params()['client_id'],
                               demisto.params()['client_secret'],
                               CHANNEL_CODE,
                               FeedStream.DARKFEED,
                               demisto, max_indicators, SESSION, VERIFY)

    command = demisto.command()
    demisto.info(f'Command being called is {command}')
    tags = argToList(demisto.params().get('feedTags', []))
    tlp_color = demisto.params().get('tlp_color')
    commands: Dict[str, Callable] = {
        'test-module': test_module_command,
        'sixgill-get-indicators': get_indicators_command
    }
    try:
        if demisto.command() == 'fetch-indicators':
            indicators = fetch_indicators_command(client, tags=tags, tlp_color=tlp_color)
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            readable_output, outputs, raw_response = commands[command](client, demisto.args())

            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        demisto.error(traceback.format_exc())
        return_error(f'Error failed to execute {demisto.command()}, error: [{e}]')
def fetch_incidents():
    last_fetch = get_last_fetch_time()
    es = elasticsearch_builder()

    query = QueryString(query=FETCH_QUERY + " AND " + TIME_FIELD + ":*")
    search = Search(using=es, index=FETCH_INDEX).filter(
        {'range': {
            TIME_FIELD: {
                'gt': last_fetch
            }
        }})
    search = search.sort({TIME_FIELD: {
        'order': 'asc'
    }})[0:FETCH_SIZE].query(query)
    response = search.execute().to_dict()
    _, total_results = get_total_results(response)

    incidents = []  # type: List

    if total_results > 0:
        if 'Timestamp' in TIME_METHOD:
            incidents, last_fetch = results_to_incidents_timestamp(
                response, last_fetch)
            demisto.setLastRun({'time': last_fetch})

        else:
            incidents, last_fetch = results_to_incidents_datetime(
                response, last_fetch)
            demisto.setLastRun(
                {'time': datetime.strftime(last_fetch, TIME_FORMAT)})

        demisto.info('extract {} incidents'.format(len(incidents)))

    demisto.incidents(incidents)
def generate_incidents(last_run):
    """
    Determines how many incidents to create and generates them

    parameter: (number) last_run
        The number of incidents generated in the last fetch

    returns:
        The number of incidents generated in the current call to fetch_incidents and the incidents themselves
    """
    if last_run > 0 and last_run > MAX_NUM_OF_INCIDENTS:
        demisto.info('last_run is greater than MAX_NUM_OF_INCIDENTS')
        return 0, []

    incidents = []
    num_of_incidents_left_to_create = MAX_NUM_OF_INCIDENTS - last_run

    if num_of_incidents_left_to_create > INCIDENTS_PER_MINUTE:
        num_of_incident_to_create = INCIDENTS_PER_MINUTE
    else:
        num_of_incident_to_create = num_of_incidents_left_to_create

    for _ in range(num_of_incident_to_create):
        email, email_object = create_email()
        incidents.append({
            'name': email_object.get('Subject'),
            'details': email.as_string(),
            'occurred': email_object.get('Date'),
            'type': INCIDENT_TYPE,
            'rawJSON': json.dumps(email_object)
        })
    return num_of_incident_to_create, incidents
def main():
    params = demisto.params()

    client = Client(params.get('api_key'), params.get('insecure'),
                    params.get('proxy'), params.get('indicator_feeds'),
                    params.get('custom_feed_urls'))

    command = demisto.command()
    demisto.info(f'Command being called is {command}')
    # Switch case
    commands = {
        'test-module': module_test_command,
        'autofocus-get-indicators': get_indicators_command
    }
    try:
        if demisto.command() == 'fetch-indicators':
            indicators = fetch_indicators_command(client)
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            readable_output, outputs, raw_response = commands[command](
                client, demisto.args())
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        raise Exception(f'Error in {SOURCE_NAME} Integration [{e}]')
def update_alert_status():
    """
    Updates the actionable alert status.
    """
    args = demisto.args()
    alert_status = args.get('alert_status')
    alert_id = args.get('alert_id')
    aggregate_alert_id = args.get('aggregate_alert_id')
    demisto.info(
        "update_alert_status: status - {}, alert_id - {}, aggregate_alert_id - {}"
        .format(alert_status, alert_id, aggregate_alert_id))
    aggregate_alert_id = [int(aggregate_alert_id)
                          ] if aggregate_alert_id else aggregate_alert_id
    alert_body = {"status": {"status": alert_status}}

    sixgill_alerts_client = SixgillActionableAlertClient(
        client_id=demisto.params()['client_id'],
        client_secret=demisto.params()['client_secret'],
        channel_id=CHANNEL_CODE,
        logger=demisto,
        session=SESSION,
        verify=VERIFY)

    res = sixgill_alerts_client.update_actionable_alert(
        actionable_alert_id=alert_id,
        json_body=alert_body,
        sub_alert_indexes=aggregate_alert_id)

    if res.get('status') == 200:
        demisto.results("Actionable alert status updated")
Exemple #8
0
def feed_main(feed_name, params, prefix=''):
    params['feed_name'] = feed_name
    client = Client(**params)
    command = demisto.command()
    if command != 'fetch-indicators':
        demisto.info('Command being called is {}'.format(command))
    if prefix and not prefix.endswith('-'):
        prefix += '-'
    # Switch case
    commands: dict = {
        'test-module': test_module,
        f'{prefix}get-indicators': get_indicators_command
    }
    try:
        if command == 'fetch-indicators':
            indicators = fetch_indicators_command(client, params.get('indicator_type'))
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            args = demisto.args()
            args['feed_name'] = feed_name
            readable_output, outputs, raw_response = commands[command](client, args)
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        err_msg = f'Error in {feed_name} integration [{e}]\nTrace\n:{traceback.format_exc()}'
        return_error(err_msg)
Exemple #9
0
async def slack_loop():
    """
    Starts a Slack RTM client while checking the connection.
    """
    while True:
        loop = asyncio.get_running_loop()
        rtm_client = None
        try:
            rtm_client = slack.RTMClient(token=TOKEN,
                                         run_async=True,
                                         loop=loop,
                                         auto_reconnect=False)
            client_future = rtm_client.start()
            while True:
                await asyncio.sleep(10)
                if rtm_client._websocket is None or rtm_client._websocket.closed or client_future.done(
                ):
                    ex = client_future.exception()
                    if ex:
                        demisto.error(
                            'Slack client raised an exception: {}'.format(ex))
                    demisto.info('Slack - websocket is closed or done')
                    break
        except Exception as e:
            error = 'Slack client raised an exception: {}'.format(e)
            await handle_listen_error(error)
        finally:
            # If we got here, the websocket is closed or the client can't connect. Will try to connect every 5 seconds.
            if rtm_client and not rtm_client._stopped:
                rtm_client.stop()
            await asyncio.sleep(5)
Exemple #10
0
def main():
    client = Client(
        demisto.getParam("api_access_id"),
        demisto.getParam("api_secret_key"),
        demisto.getParam("tc_api_path"),
    )
    command = demisto.command()
    demisto.info(f'Command being called is {command}')
    commands = {
        'test-module': module_test_command,
        f'{INTEGRATION_COMMAND_NAME}-get-indicators': get_indicators_command,
        f'{INTEGRATION_COMMAND_NAME}-get-owners': get_owners_command
    }
    try:
        if demisto.command() == 'fetch-indicators':
            indicators = fetch_indicators_command(client)
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            readable_output, outputs, raw_response = commands[command](client)
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        return_error(
            f'Integration {INTEGRATION_NAME} Failed to execute {command} command. Error: {str(e)}'
        )
Exemple #11
0
def check_for_mirrors():
    """
    Checks for newly created mirrors and updates the server accordingly
    """
    integration_context = demisto.getIntegrationContext()
    if integration_context.get('mirrors'):
        mirrors = json.loads(integration_context['mirrors'])
        for mirror in mirrors:
            if not mirror['mirrored']:
                demisto.info('Mirroring: {}'.format(
                    mirror['investigation_id']))
                mirror = mirrors.pop(mirrors.index(mirror))
                if mirror['mirror_to'] and mirror[
                        'mirror_direction'] and mirror['mirror_type']:
                    investigation_id = mirror['investigation_id']
                    mirror_type = mirror['mirror_type']
                    auto_close = mirror['auto_close']
                    direction = mirror['mirror_direction']
                    if isinstance(auto_close, str):
                        auto_close = bool(strtobool(auto_close))
                    demisto.mirrorInvestigation(
                        investigation_id,
                        '{}:{}'.format(mirror_type, direction), auto_close)
                    mirror['mirrored'] = True
                    mirrors.append(mirror)
                else:
                    demisto.info('Could not mirror {}'.format(
                        mirror['investigation_id']))

                set_to_latest_integration_context('mirrors', mirrors)
Exemple #12
0
def main():
    params = demisto.params()
    feed_tags = argToList(params.get('feedTags'))
    tlp_color = params.get('tlp_color')

    command = demisto.command()
    demisto.info(f'Command being called is {command}')
    # Switch case
    commands = {
        'test-module': module_test_command,
        'autofocus-get-indicators': get_indicators_command
    }
    try:
        auto_focus_key_retriever = AutoFocusKeyRetriever(params.get('api_key'))
        client = Client(api_key=auto_focus_key_retriever.key,
                        insecure=params.get('insecure'),
                        proxy=params.get('proxy'),
                        indicator_feeds=params.get('indicator_feeds'),
                        custom_feed_urls=params.get('custom_feed_urls'),
                        scope_type=params.get('scope_type'),
                        sample_query=params.get('sample_query'))

        if demisto.command() == 'fetch-indicators':
            indicators = fetch_indicators_command(client, feed_tags, tlp_color)
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            readable_output, outputs, raw_response = commands[command](
                client, demisto.args(), feed_tags, tlp_color)  # type: ignore
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        raise Exception(f'Error in {SOURCE_NAME} Integration [{e}]')
def main():
    params = demisto.params()
    client = Client(params.get('indicator_type'), params.get('api_token'),
                    params.get('services'), params.get('risk_rule'),
                    params.get('fusion_file_path'), params.get('insecure'),
                    params.get('polling_timeout'), params.get('proxy'),
                    params.get('threshold'))
    command = demisto.command()
    demisto.info('Command being called is {}'.format(command))
    # Switch case
    commands = {
        'test-module': test_module,
        'rf-feed-get-indicators': get_indicators_command,
        'rf-feed-get-risk-rules': get_risk_rules_command
    }
    try:
        if demisto.command() == 'fetch-indicators':
            indicators = fetch_indicators_command(client,
                                                  client.indicator_type)
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        else:
            readable_output, outputs, raw_response = commands[command](
                client, demisto.args())  # type:ignore
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        err_msg = f'Error in {INTEGRATION_NAME} Integration [{e}] \n Traceback: {traceback.format_exc()}'
        return_error(err_msg)
Exemple #14
0
def update_incident(incident_id, assigned_user_mail, assigned_user_pretty_name,
                    status, severity, resolve_comment, unassign_user):
    update_data = {}

    if unassign_user and (assigned_user_mail or assigned_user_pretty_name):
        raise ValueError(
            "Can't provide both assignee_email/assignee_name and unassign_user"
        )
    elif unassign_user:
        update_data['assigned_user_mail'] = 'none'

    if assigned_user_mail:
        update_data['assigned_user_mail'] = assigned_user_mail

    if assigned_user_pretty_name:
        update_data['assigned_user_pretty_name'] = assigned_user_pretty_name

    if status:
        update_data['status'] = status

    if severity:
        update_data['manual_severity'] = severity

    if resolve_comment:
        update_data['resolve_comment'] = resolve_comment

    request_data = {'incident_id': incident_id, 'update_data': update_data}
    demisto.info(json.dumps(request_data, indent=4))
    http_request('POST',
                 '/incidents/update_incident/',
                 data={'request_data': request_data})
Exemple #15
0
 def get_versions(self, versions_filter: str):
     """
     :param versions_filter: (str) contains the filter of the request.
     :return: the result of the http request from the api
     """
     demisto.info(f'fileters for version {versions_filter}')
     return self._http_request(method='GET', url_suffix=URL_SUFFIX['VERSIONS'].format(versions_filter))
def main():
    params = demisto.params()
    args = demisto.args()
    base_url = "https://rules.emergingthreats.net/"
    client = Client(
        base_url=base_url,
        auth_code=params.get("auth_code"),
        verify=not params.get("insecure", False),
        proxy=params.get("proxy"),
    )
    command = demisto.command()
    demisto.info("Command being called is {}".format(command))
    # Switch case
    try:
        if command == "fetch-indicators":
            indicators = fetch_indicators_command(client,
                                                  params.get("indicator_type"))
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
        elif command == "test-module":
            return_outputs(
                module_test_command(client, params.get("indicator_type")))
        elif command == "proofpoint-get-indicators":
            readable_output, outputs, raw_response = get_indicators_command(
                client, args)
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        return_error(
            f"Error in {SOURCE_NAME} Integration - Encountered an issue with createIndicators"
            if "failed to create" in
            str(e) else f"Error in {SOURCE_NAME} Integration [{e}]")
Exemple #17
0
def main():
    # Write configure here
    params = {k: v for k, v in demisto.params().items() if v is not None}
    handle_proxy()
    client = TAXIIClient(**params)
    command = demisto.command()
    demisto.info('Command being called is {command}'.format(command=command))
    # Switch case
    commands = {
        'test-module': test_module,
        'get-indicators': get_indicators_command
    }
    try:
        if demisto.command() == 'fetch-indicators':
            indicators = fetch_indicators_command(client)
            # we submit the indicators in batches
            for b in batch(indicators, batch_size=2000):
                demisto.createIndicators(b)
            demisto.setLastRun({'time': client.last_taxii_run})
        else:
            readable_output, outputs, raw_response = commands[command](client, demisto.args())
            return_outputs(readable_output, outputs, raw_response)
    except Exception as e:
        err_msg = f'Error in {INTEGRATION_NAME} Integration [{e}]'
        raise Exception(err_msg)
Exemple #18
0
def find_indicators_by_time_frame(indicator_query: str, begin_time: datetime, end_time: datetime) -> list:
    """
    Find indicators according to a query and begin time/end time.
    Args:
        indicator_query: The indicator query.
        begin_time: The exclusive begin time.
        end_time: The inclusive end time.

    Returns:
        Indicator query results from Demisto.
    """

    if indicator_query:
        indicator_query += ' and '
    else:
        indicator_query = ''

    if begin_time:
        tz_begin_time = datetime.strftime(begin_time, '%Y-%m-%dT%H:%M:%S %z')
        indicator_query += f'sourcetimestamp:>"{tz_begin_time}"'
        if end_time:
            indicator_query += ' and '
    if end_time:
        tz_end_time = datetime.strftime(end_time, '%Y-%m-%dT%H:%M:%S %z')
        indicator_query += f'sourcetimestamp:<="{tz_end_time}"'
    demisto.info(f'Querying indicators by: {indicator_query}')

    return find_indicators_loop(indicator_query)
Exemple #19
0
def webhook_event_send_command(client: Client, args: dict):
    auth_token = args.get("auth_token", "")
    options: str = args.get("options", "")
    free_json: str = args.get("json", "")
    options_as_dict: dict = attribute_pairs_to_dict(options)

    try:
        demisto.info('start convert "options" argument to str')
        if options_as_dict:
            options_as_str: str = json.dumps(options_as_dict)
        else:
            options_as_str = free_json
            demisto.info('finish convert "options" argument to str')
    except Exception as e:
        raise DemistoException(
            f'There was a problem converting "json" to json. The reason is: {e}'
        )
    result = client.webhook_event_send(auth_token, options_as_str, free_json)

    headers = [key.replace("_", " ") for key in [*result.keys()]]
    readable_output = tableToMarkdown(
        "Webhook event send:", result, headers=headers, headerTransform=pascalToSpace
    )
    return CommandResults(
        readable_output=readable_output,
        outputs_prefix="Rundeck.WebhookEvent",
        outputs=result,
        outputs_key_field="id",
    )
def generate_incidents(last_run):
    """
    Determines how many incidents to create and generates them

    parameter: (number) last_run
        The number of incidents generated in the last fetch

    returns:
        The number of incidents generated in the current call to fetch_incidents and the incidents themselves
    """
    if last_run > 0 and last_run > MAX_NUM_OF_INCIDENTS:
        demisto.info('last_run is greater than MAX_NUM_OF_INCIDENTS')
        return 0, []

    incidents = []
    num_of_incidents_left_to_create = MAX_NUM_OF_INCIDENTS - last_run

    if num_of_incidents_left_to_create > INCIDENTS_PER_MINUTE:
        num_of_incident_to_create = INCIDENTS_PER_MINUTE
    else:
        num_of_incident_to_create = num_of_incidents_left_to_create

    for _ in range(num_of_incident_to_create):
        email, email_object = create_email()
        incidents.append({
            'name': email_object.get('Subject'),
            'details': email.as_string(),
            'occurred': email_object.get('Date'),
            'type': INCIDENT_TYPE,
            'rawJSON': json.dumps(email_object)
        })
    return num_of_incident_to_create, incidents
def docker_auth(image_name, verify_ssl=True, registry=DEFAULT_REGISTRY):
    """
    Authenticate to the docker service. Return an authentication token if authentication is required.
    """
    res = requests.get("https://{}/v2/".format(registry), headers=ACCEPT_HEADER,
                       timeout=TIMEOUT, verify=verify_ssl)
    if res.status_code == 401:  # need to authenticate
        # defaults in case we fail for some reason
        realm = "https://auth.docker.io/token"
        service = "registry.docker.io"
        # Shold contain header: Www-Authenticate
        www_auth = res.headers.get('www-authenticate')
        if www_auth:
            parse_auth = parse_www_auth(www_auth)
            if parse_auth:
                realm, service = parse_auth
            else:
                demisto.info('Failed parsing www-authenticate header: {}'.format(www_auth))
        else:
            demisto.info('Failed extracting www-authenticate header from registry: {}, final url: {}'.format(
                registry, res.url))
        res = requests.get(
            "{}?scope=repository:{}:pull&service={}".format(realm, image_name, service),
            headers=ACCEPT_HEADER, timeout=TIMEOUT, verify=verify_ssl)
        res.raise_for_status()
        res_json = res.json()
        return res_json.get('token')
    else:
        res.raise_for_status()
        return None
Exemple #22
0
def main():
    params = demisto.params()
    username = params.get('credentials').get('identifier')
    password = params.get('credentials').get('password')
    domain = params.get('domain')
    # Remove trailing slash to prevent wrong URL path to service
    server = params['url'].strip('/')
    # Service base URL
    base_url = server + '/api/v2/'
    # Should we use SSL
    use_ssl = not params.get('insecure', False)

    # Remove proxy if not set to true in params
    handle_proxy()
    command = demisto.command()
    client = Client(base_url, username, password, domain, verify=use_ssl)
    demisto.info(f'Command being called is {command}')

    commands = {
        'test-module': test_module,
        'tn-get-system-status': get_system_status,
        'tn-get-package': get_package,
        'tn-create-package': create_package,
        'tn-list-packages': get_packages,
        'tn-get-sensor': get_sensor,
        'tn-list-sensors': get_sensors,
        'tn-ask-question': ask_question,
        'tn-get-question-metadata': get_question_metadata,
        'tn-get-question-result': get_question_result,
        'tn-create-saved-question': create_saved_question,
        'tn-get-saved-question-metadata': get_saved_question_metadata,
        'tn-get-saved-question-result': get_saved_question_result,
        'tn-list-saved-questions': get_saved_questions,
        'tn-create-action': create_action,
        'tn-create-action-by-host': create_action_by_host,
        'tn-get-action': get_action,
        'tn-list-actions': get_actions,
        'tn-create-saved-action': create_saved_action,
        'tn-get-saved-action': get_saved_action,
        'tn-list-saved-actions': get_saved_actions,
        'tn-list-saved-actions-pending-approval': get_saved_actions_pending,
        'tn-create-filter-based-group': create_filter_based_group,
        'tn-create-manual-group': create_manual_group,
        'tn-get-group': get_group,
        'tn-list-groups': get_groups,
        'tn-delete-group': delete_group
    }

    try:
        if command in commands:
            human_readable, outputs, raw_response = commands[command](
                client, demisto.args())
            return_outputs(readable_output=human_readable,
                           outputs=outputs,
                           raw_response=raw_response)
        # Log exceptions
    except Exception as e:
        err_msg = f'Error in Tanium v2 Integration [{e}]'
        return_error(err_msg, error=e)
Exemple #23
0
    def write(message):
        """
        Writes a log message to the Demisto server.
        Args:
            message: The log message to write

        """
        demisto.info(message)
Exemple #24
0
 def get_last_run() -> str:
     """ Gets last run time in timestamp
     Returns:
         last run in timestamp, or '' if no last run
     """
     if last_run := demisto.getIntegrationContext().get('last_run'):
         demisto.info(f'get last_run: {last_run}')
         params = f'date:{last_run}+'
Exemple #25
0
def base_dn_verified(base_dn):
    # serch AD with a simple query to test base DN is configured correctly
    try:
        search("(objectClass=user)", base_dn, size_limit=1)
    except Exception as e:
        demisto.info(str(e))
        return False
    return True
Exemple #26
0
def process_attachments(attachCIDs="",
                        attachIDs="",
                        attachNames="",
                        manualAttachObj=None):
    if manualAttachObj is None:
        manualAttachObj = []
    file_entries_for_attachments = []  # type: list
    attachments_names = []  # type: list

    if attachIDs:
        file_entries_for_attachments = attachIDs if isinstance(
            attachIDs, list) else attachIDs.split(",")
        if attachNames:
            attachments_names = attachNames if isinstance(
                attachNames, list) else attachNames.split(",")
        else:
            for att_id in file_entries_for_attachments:
                att_name = demisto.getFilePath(att_id)['name']
                if isinstance(att_name, list):
                    att_name = att_name[0]
                attachments_names.append(att_name)
        if len(file_entries_for_attachments) != len(attachments_names):
            raise Exception(
                "attachIDs and attachNames lists should be the same length")

    attachments = collect_manual_attachments(manualAttachObj)

    if attachCIDs:
        file_entries_for_attachments_inline = attachCIDs if isinstance(
            attachCIDs, list) else attachCIDs.split(",")
        for att_id_inline in file_entries_for_attachments_inline:
            try:
                file_info = demisto.getFilePath(att_id_inline)
            except Exception as ex:
                demisto.info("EWS error from getFilePath: {}".format(ex))
                raise Exception("entry %s does not contain a file" %
                                att_id_inline)
            att_name_inline = file_info["name"]
            with open(file_info["path"], 'rb') as f:
                attachments.append(
                    FileAttachment(content=f.read(),
                                   name=att_name_inline,
                                   is_inline=True,
                                   content_id=att_name_inline))

    for i in range(0, len(file_entries_for_attachments)):
        entry_id = file_entries_for_attachments[i]
        attachment_name = attachments_names[i]
        try:
            res = demisto.getFilePath(entry_id)
        except Exception as ex:
            raise Exception("entry {} does not contain a file: {}".format(
                entry_id, str(ex)))
        file_path = res["path"]
        with open(file_path, 'rb') as f:
            attachments.append(
                FileAttachment(content=f.read(), name=attachment_name))
    return attachments, attachments_names
def fetch_incidents(proxies):
    last_run = demisto.getLastRun()
    last_fetch = last_run.get('time')

    # handle first time fetch
    if last_fetch is None:
        last_fetch, _ = parse_date_range(date_range=FETCH_TIME,
                                         date_format='%Y-%m-%dT%H:%M:%S.%f',
                                         utc=False,
                                         to_timestamp=False)
        last_fetch = parse(str(last_fetch))
        last_fetch_timestamp = int(last_fetch.timestamp() * 1000)

        # if timestamp: get the last fetch to the correct format of timestamp
        if 'Timestamp' in TIME_METHOD:
            last_fetch = get_timestamp_first_fetch(last_fetch)
            last_fetch_timestamp = last_fetch

    # if method is simple date - convert the date string to datetime
    elif 'Simple-Date' == TIME_METHOD:
        last_fetch = parse(str(last_fetch))
        last_fetch_timestamp = int(last_fetch.timestamp() * 1000)

    # if last_fetch is set and we are in a "Timestamp" method - than the last_fetch_timestamp is the last_fetch.
    else:
        last_fetch_timestamp = last_fetch

    es = elasticsearch_builder(proxies)

    query = QueryString(query=FETCH_QUERY + " AND " + TIME_FIELD + ":*")
    # Elastic search can use epoch timestamps (in milliseconds) as date representation regardless of date format.
    search = Search(using=es, index=FETCH_INDEX).filter(
        {'range': {
            TIME_FIELD: {
                'gt': last_fetch_timestamp
            }
        }})
    search = search.sort({TIME_FIELD: {
        'order': 'asc'
    }})[0:FETCH_SIZE].query(query)
    response = search.execute().to_dict()
    _, total_results = get_total_results(response)

    incidents = []  # type: List

    if total_results > 0:
        if 'Timestamp' in TIME_METHOD:
            incidents, last_fetch = results_to_incidents_timestamp(
                response, last_fetch)
            demisto.setLastRun({'time': last_fetch})

        else:
            incidents, last_fetch = results_to_incidents_datetime(
                response, last_fetch)
            demisto.setLastRun({'time': str(last_fetch)})

        demisto.info('extract {} incidents'.format(len(incidents)))
    demisto.incidents(incidents)
Exemple #28
0
def get_access_token():
    integration_context = demisto.getIntegrationContext()
    access_token = integration_context.get('access_token')
    valid_until = integration_context.get('valid_until')
    if access_token and valid_until:
        if epoch_seconds() < valid_until:
            return access_token
    headers = {'Accept': 'application/json'}

    dbot_response = requests.post(
        TOKEN_RETRIEVAL_URL,
        headers=headers,
        data=json.dumps({
            'app_name': APP_NAME,
            'registration_id': AUTH_ID,
            'encrypted_token': get_encrypted(TENANT_ID, ENC_KEY)
        }),
        verify=USE_SSL
    )
    if dbot_response.status_code not in {200, 201}:
        msg = 'Error in authentication. Try checking the credentials you entered.'
        try:
            demisto.info('Authentication failure from server: {} {} {}'.format(
                dbot_response.status_code, dbot_response.reason, dbot_response.text))
            err_response = dbot_response.json()
            server_msg = err_response.get('message')
            if not server_msg:
                title = err_response.get('title')
                detail = err_response.get('detail')
                if title:
                    server_msg = f'{title}. {detail}'
            if server_msg:
                msg += ' Server message: {}'.format(server_msg)
        except Exception as ex:
            demisto.error('Failed parsing error response - Exception: {}'.format(ex))
        raise Exception(msg)
    try:
        gcloud_function_exec_id = dbot_response.headers.get('Function-Execution-Id')
        demisto.info(f'Google Cloud Function Execution ID: {gcloud_function_exec_id}')
        parsed_response = dbot_response.json()
    except ValueError:
        raise Exception(
            'There was a problem in retrieving an updated access token.\n'
            'The response from the Demistobot server did not contain the expected content.'
        )
    access_token = parsed_response.get('access_token')
    expires_in = parsed_response.get('expires_in', 3595)
    time_now = epoch_seconds()
    time_buffer = 5  # seconds by which to shorten the validity period
    if expires_in - time_buffer > 0:
        # err on the side of caution with a slightly shorter access token validity period
        expires_in = expires_in - time_buffer

    demisto.setIntegrationContext({
        'access_token': access_token,
        'valid_until': time_now + expires_in
    })
    return access_token
Exemple #29
0
def main() -> None:
    """main function, parses params and runs command functions

    :return:
    :rtype:
    """

    # INTEGRATION DEVELOPER TIP
    # You can use functions such as ``demisto.debug()``, ``demisto.info()``,
    # etc. to print information in the XSOAR server log. You can set the log
    # level on the server configuration
    # See: https://xsoar.pan.dev/docs/integrations/code-conventions#logging

    command = demisto.command()
    args = demisto.args()
    demisto.info(f'Command running: {demisto.command()}')

    try:
        client = create_client()
        xm = XM(client)

        # commands dict
        # key - command key
        # value - command execution function that get two params:
        #         1) XM object
        #         2) args dict
        #         return value - CommandResults
        commandsDict = {
            "test-module":
            test_module_command_internal,  # This is the call made when pressing the integration Test button.
            "xmcyber-f-incidents":
            fetch_incidents_command,  # for debugging of fetch incidents
            # XM Cyber Command list
            # xmcyber-command-name: function_command
            "xmcyber-version-get": get_version_command,
            "xmcyber-version-supported": is_xm_version_supported_command,
            "xmcyber-affected-critical-assets-list":
            affected_critical_assets_list_command,
            "xmcyber-affected-entities-list": affected_entities_list_command,
            # Common commands
            "ip": ip_command,
            "xmcyber-hostname": hostname_command
        }

        if command == 'fetch-incidents':
            xm.is_fetch_incidents = True
            fetch_incidents_command(xm, args)
        elif command in commandsDict:
            return_results(commandsDict[command](xm, args))
        else:
            raise Exception("Unsupported command: " + command)

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(
            f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}\n'
            f'Traceback:\n{traceback.format_exc()}')
Exemple #30
0
def main() -> None:
    """main function, parses params and runs command functions

    :return:
    :rtype:
    """

    polaris_account = demisto.params().get('polaris_account', False)
    polaris_domain_name = "my.rubrik.com"
    polaris_base_url = f"https://{polaris_account}.{polaris_domain_name}/api"

    headers = {
        'Content-Type': 'application/json;charset=UTF-8',
        'Accept': 'application/json, text/plain'
    }

    client = Client(base_url=polaris_base_url, headers=headers, verify=False)

    max_fetch = demisto.params().get('max_fetch')
    max_fetch = int(demisto.params().get('max_fetch')) if (
        max_fetch and max_fetch.isdigit()) else 50
    max_fetch = max(min(200, max_fetch), 1)

    demisto.info(f'Command being called is {demisto.command()}')
    try:
        if demisto.command() == 'test-module':
            # This is the call made when pressing the integration Test button.
            result = test_module(client)
            return_results(result)
        elif demisto.command() == 'fetch-incidents':
            current_time, incidents = fetch_incidents(client, max_fetch)
            # A blank current_time is returned when it has not been 5 minutes
            # since the last fetch
            if current_time != "":
                demisto.setLastRun({'last_fetch': current_time})

            demisto.incidents(incidents)

        elif demisto.command() == 'rubrik-radar-analysis-status':
            return_results(
                rubrik_radar_analysis_status_command(client, demisto.args()))
        elif demisto.command() == 'rubrik-sonar-sensitive-hits':
            return_results(
                rubrik_sonar_sensitive_hits_command(client, demisto.args()))
        elif demisto.command() == 'rubrik-cdm-cluster-location':
            return_results(
                rubrik_cdm_cluster_location_command(client, demisto.args()))
        elif demisto.command() == 'rubrik-cdm-cluster-connection-state':
            return_results(
                rubrik_cdm_cluster_connection_state_command(
                    client, demisto.args()))

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(
            f'Failed to execute {demisto.command()} command.\nError:\n{str(e)}'
        )
    async def fetch_event(self, initial_offset: int = 0, event_type: str = '') -> AsyncGenerator[Dict, None]:
        """Retrieves events from a CrowdStrike Falcon stream starting from given offset.

        Args:
            initial_offset (int): Stream offset to start the fetch from.
            event_type (str): Stream event type to fetch.

        Yields:
            AsyncGenerator[Dict, None]: Event fetched from the stream.
        """
        while True:
            demisto.debug('Fetching event')
            event = Event()
            create_task(self._discover_refresh_stream(event))
            demisto.debug('Waiting for stream discovery or refresh')
            await event.wait()
            demisto.debug('Done waiting for stream discovery or refresh')
            events_fetched = 0
            new_lines_fetched = 0
            last_fetch_stats_print = datetime.utcnow()
            async with ClientSession(
                connector=TCPConnector(ssl=self.verify_ssl),
                headers={'Authorization': f'Token {self.session_token}'},
                trust_env=self.proxy,
                timeout=None
            ) as session:
                try:
                    integration_context = demisto.getIntegrationContext()
                    offset = integration_context.get('offset', 0) or initial_offset
                    demisto.debug(f'Starting to fetch from offset {offset} events of type {event_type}')
                    async with session.get(
                        self.data_feed_url,
                        params={'offset': offset, 'eventType': event_type},
                        timeout=None
                    ) as res:
                        demisto.debug(f'Fetched event: {res.content}')
                        async for line in res.content:
                            stripped_line = line.strip()
                            if stripped_line:
                                events_fetched += 1
                                try:
                                    yield json.loads(stripped_line)
                                except json.decoder.JSONDecodeError:
                                    demisto.debug(f'Failed decoding event (skipping it) - {str(stripped_line)}')
                            else:
                                new_lines_fetched += 1
                            if last_fetch_stats_print + timedelta(minutes=1) <= datetime.utcnow():
                                demisto.info(
                                    f'Fetched {events_fetched} events and'
                                    f' {new_lines_fetched} new lines'
                                    f' from the stream in the last minute.')
                                events_fetched = 0
                                new_lines_fetched = 0
                                last_fetch_stats_print = datetime.utcnow()
                except Exception as e:
                    demisto.debug(f'Failed to fetch event: {e} - Going to sleep for 10 seconds and then retry -'
                                  f' {traceback.format_exc()}')
                    await sleep(10)
Exemple #32
0
def main():
    """
        PARSE AND VALIDATE INTEGRATION PARAMS
    """
    params = demisto.params()
    access_token = params.get('access_token')
    environment = params.get('environment')

    verify_certificate = not params.get('insecure', False)
    first_fetch_time = params.get('first_fetch', '3 days').strip()
    proxy = params.get('proxy', False)
    base_url = f'https://{environment}.cyberint.io/alert/'
    demisto.info(f'Command being called is {demisto.command()}')
    try:
        client = Client(base_url=base_url,
                        verify_ssl=verify_certificate,
                        access_token=access_token,
                        proxy=proxy)

        if demisto.command() == 'test-module':
            result = test_module(client)
            return_results(result)

        elif demisto.command() == 'fetch-incidents':
            fetch_environment = argToList(params.get('fetch_environment', ''))
            fetch_status = params.get('fetch_status', [])
            fetch_type = params.get('fetch_type', [])
            fetch_severity = params.get('fetch_severity', [])
            max_fetch = int(params.get('max_fetch', '50'))
            next_run, incidents = fetch_incidents(client, demisto.getLastRun(),
                                                  first_fetch_time,
                                                  fetch_severity, fetch_status,
                                                  fetch_type,
                                                  fetch_environment, max_fetch)
            demisto.setLastRun(next_run)
            demisto.incidents(incidents)

        elif demisto.command() == 'cyberint-alerts-fetch':
            return_results(
                cyberint_alerts_fetch_command(client, demisto.args()))

        elif demisto.command() == 'cyberint-alerts-status-update':
            return_results(
                cyberint_alerts_status_update(client, demisto.args()))
    except Exception as e:

        if 'Invalid token or token expired' in str(e):
            error_message = 'Error verifying access token and / or environment, make sure the ' \
                            'configuration parameters are correct.'
        elif 'datetime' in str(e).lower():
            error_message = 'Invalid time specified, ' \
                            'make sure the arguments are correctly formatted and are not ' \
                            'earlier than 2020 or later than the current time.'
        elif 'Unauthorized alerts requested' in str(e):
            error_message = 'Some of the alerts selected to update are either blocked or not found.'
        else:
            error_message = f'Failed to execute {demisto.command()} command. Error: {str(e)}'
        return_error(error_message)
def base_dn_verified(base_dn):
    # serch AD with a simple query to test base DN is configured correctly
    try:
        search(
            "(objectClass=user)",
            base_dn,
            size_limit=1
        )
    except Exception as e:
        demisto.info(str(e))
        return False
    return True
def get_access_token():
    integration_context = demisto.getIntegrationContext()
    access_token = integration_context.get('access_token')
    stored = integration_context.get('stored')
    if access_token and stored:
        if epoch_seconds() - stored < 60 * 60 - 30:
            return access_token
    headers = {
        'Authorization': AUTH_ID,
        'Accept': 'application/json'
    }

    dbot_response = requests.get(
        TOKEN_RETRIEVAL_URL,
        headers=headers,
        params={'token': get_encrypted(TOKEN, ENC_KEY)},
        verify=USE_SSL
    )
    if dbot_response.status_code not in {200, 201}:
        msg = 'Error in authentication. Try checking the credentials you entered.'
        try:
            demisto.info('Authentication failure from server: {} {} {}'.format(
                dbot_response.status_code, dbot_response.reason, dbot_response.text))
            err_response = dbot_response.json()
            server_msg = err_response.get('message')
            if server_msg:
                msg += ' Server message: {}'.format(server_msg)
        except Exception as ex:
            demisto.error('Failed parsing error response: [{}]. Exception: {}'.format(err_response.content, ex))
        raise Exception(msg)
    try:
        parsed_response = dbot_response.json()
    except ValueError:
        raise Exception(
            'There was a problem in retrieving an updated access token.\n'
            'The response from the Demistobot server did not contain the expected content.'
        )
    access_token = parsed_response.get('access_token')
    api_url = parsed_response.get('url')
    token = parsed_response.get('token')

    demisto.setIntegrationContext({
        'access_token': access_token,
        'stored': epoch_seconds(),
        'api_url': api_url,
        'token': token
    })
    return access_token
Exemple #35
0
def fetch_incidents():
    params = demisto.params()
    user_key = params.get('queryUserKey')
    user_key = user_key if user_key else ADMIN_EMAIL
    query = '' if params['query'] is None else params['query']
    last_run = demisto.getLastRun()
    last_fetch = last_run.get('time')

    # handle first time fetch
    if last_fetch is None:
        last_fetch = datetime.datetime.now() - datetime.timedelta(days=1)
    else:
        last_fetch = datetime.datetime.strptime(
            last_fetch, '%Y-%m-%dT%H:%M:%SZ')
    current_fetch = last_fetch

    credentials = get_credentials(
        ['https://www.googleapis.com/auth/gmail.readonly', ], user_key)
    service = discovery.build('gmail', 'v1', credentials=credentials)

    query += last_fetch.strftime(' after:%Y/%m/%d')
    LOG('GMAIL: fetch parameters:\nuser: %s\nquery=%s\nfetch time: %s' %
        (user_key, query, last_fetch, ))

    result = service.users().messages().list(
        userId=user_key, maxResults=100, q=query).execute()

    incidents = []
    # so far, so good
    LOG('GMAIL: possible new incidents are %s' % (result, ))
    for msg in result.get('messages', []):
        msg_result = service.users().messages().get(
            id=msg['id'], userId=user_key).execute()
        incident = mail_to_incident(msg_result, service, user_key)
        temp_date = datetime.datetime.strptime(
            incident['occurred'], '%Y-%m-%dT%H:%M:%SZ')

        # update last run
        if temp_date > last_fetch:
            last_fetch = temp_date + datetime.timedelta(seconds=1)

        # avoid duplication due to weak time query
        if temp_date > current_fetch:
            incidents.append(incident)
    demisto.info('extract {} incidents'.format(len(incidents)))
    demisto.setLastRun({'time': last_fetch.isoformat().split('.')[0] + 'Z'})
    return incidents
def main():
    if demisto.args().get('use_system_proxy') == 'no':
        del os.environ['HTTP_PROXY']
        del os.environ['HTTPS_PROXY']
        del os.environ['http_proxy']
        del os.environ['https_proxy']
    verify_ssl = demisto.args().get('trust_any_certificate') != 'yes'
    docker_full_name = demisto.args()['input']
    registry = DEFAULT_REGISTRY
    image_name_tag = docker_full_name
    if docker_full_name.count('/') > 1:
        registry, image_name_tag = docker_full_name.split('/', 1)
    try:
        split = image_name_tag.split(':')
        image_name = split[0]
        tag = 'latest'
        if len(split) > 1:
            tag = split[1]
        if tag is None:
            tag = 'latest'
        auth_token = docker_auth(image_name, verify_ssl, registry)
        headers = ACCEPT_HEADER.copy()
        if auth_token:
            headers['Authorization'] = "Bearer {}".format(auth_token)
        res = requests.get("https://{}/v2/{}/manifests/{}".format(registry, image_name, tag),
                           headers=headers, timeout=TIMEOUT, verify=verify_ssl)
        res.raise_for_status()
        layers = res.json().get('layers')
        if not layers:
            raise ValueError("No 'layers' found in json response: {}".format(res.content))
        layer_min = docker_min_layer(layers)
        headers['Range'] = "bytes=0-99"
        res = requests.get("https://{}/v2/{}/blobs/{}".format(registry, image_name, layer_min['digest']),
                           headers=headers, timeout=TIMEOUT, verify=verify_ssl)
        res.raise_for_status()
        expected_len = min([100, layer_min['size']])
        cont_len = len(res.content)
        demisto.info("Docker image check [{}] downloaded layer content of len: {}".format(docker_full_name, cont_len))
        if cont_len < expected_len:
            raise ValueError('Content returned is shorter than expected length: {}. Content: {}'.format(expected_len,
                             res.content))
        demisto.results('ok')
    except Exception as ex:
        return_error("Failed verifying: {}. Err: {}".format(docker_full_name, str(ex)))
def create_contact():
    assert conn is not None
    args = demisto.args()

    object_classes = ["top", "person", "organizationalPerson", "contact"]
    contact_dn = args.get('contact-dn')

    # set contact attributes
    attributes: Dict = {}
    if args.get('custom-attributes'):
        try:
            attributes = json.loads(args['custom-attributes'])
        except Exception as e:
            demisto.info(str(e))
            raise Exception(
                'Failed to parse custom attributes argument. Please see an example of this argument in the argument.'
            )

    # set common user attributes
    if args.get('diaply-name'):
        attributes['displayName'] = args['diaply-name']
    if args.get('description'):
        attributes['description'] = args['description']
    if args.get('email'):
        attributes['mail'] = args['email']
    if args.get('telephone-number'):
        attributes['telephoneNumber'] = args['telephone-number']
    if args.get('title'):
        attributes['title'] = args['title']

    # add contact

    success = conn.add(contact_dn, object_classes, attributes)
    if not success:
        raise Exception("Failed to create contact")

    demisto_entry = {
        'ContentsFormat': formats['text'],
        'Type': entryTypes['note'],
        'Contents': "Created contact with DN: {}".format(contact_dn)
    }
    demisto.results(demisto_entry)
def create_user():
    assert conn is not None
    args = demisto.args()

    object_classes = ["top", "person", "organizationalPerson", "user"]
    user_dn = args.get('user-dn')
    username = args.get("username")
    password = args.get("password")
    custome_attributes = args.get('custom-attributes')
    attributes = {
        "samAccountName": username
    }

    # set common user attributes
    if args.get('display-name'):
        attributes['displayName'] = args['display-name']
    if args.get('description'):
        attributes['description'] = args['description']
    if args.get('email'):
        attributes['mail'] = args['email']
    if args.get('telephone-number'):
        attributes['telephoneNumber'] = args['telephone-number']
    if args.get('title'):
        attributes['title'] = args['title']

    # set user custome attributes
    if custome_attributes:
        try:
            custome_attributes = json.loads(custome_attributes)
        except Exception as e:
            demisto.info(str(e))
            raise Exception(
                "Failed to parse custom attributes argument. Please see an example of this argument in the description."
            )
        for attribute_name, attribute_value in custome_attributes.items():
            # can run default attribute stting
            attributes[attribute_name] = attribute_value

    # add user
    success = conn.add(user_dn, object_classes, attributes)
    if not success:
        raise Exception("Failed to create user")

    # set user password
    success = conn.extend.microsoft.modify_password(user_dn, password)
    if not success:
        raise Exception("Failed to reset user password")

    # enable user and expire password
    modification = {
        # enable user
        'userAccountControl': [('MODIFY_REPLACE', NORMAL_ACCOUNT)],
        # set to 0, to force password change on next login
        "pwdLastSet": [('MODIFY_REPLACE', "0")]
    }
    modify_object(user_dn, modification)

    demisto_entry = {
        'ContentsFormat': formats['text'],
        'Type': entryTypes['note'],
        'Contents': "Created user with DN: {}".format(user_dn)
    }
    demisto.results(demisto_entry)
def main():
    ''' INSTANCE CONFIGURATION '''
    SERVER_IP = demisto.params().get('server_ip')
    USERNAME = demisto.params().get('credentials')['identifier']
    PASSWORD = demisto.params().get('credentials')['password']
    DEFAULT_BASE_DN = demisto.params().get('base_dn')
    SECURE_CONNECTION = demisto.params().get('secure_connection')
    DEFAULT_PAGE_SIZE = int(demisto.params().get('page_size'))
    NTLM_AUTH = demisto.params().get('ntlm')
    UNSECURE = demisto.params().get('unsecure', False)
    PORT = demisto.params().get('port')

    if PORT:
        # port was configured, cast to int
        PORT = int(PORT)

    try:
        server = initialize_server(SERVER_IP, PORT, SECURE_CONNECTION, UNSECURE)
    except Exception as e:
        return_error(str(e))
        return
    global conn
    if NTLM_AUTH:
        # intialize connection to LDAP server with NTLM authentication
        # user example: domain\user
        domain_user = SERVER_IP + '\\' + USERNAME if '\\' not in USERNAME else USERNAME
        conn = Connection(server, user=domain_user, password=PASSWORD, authentication=NTLM)
    else:
        # here username should be the user dn
        conn = Connection(server, user=USERNAME, password=PASSWORD)

    # bind operation is the “authenticate” operation.
    try:
        # open socket and bind to server
        if not conn.bind():
            message = "Failed to bind to server. Please validate the credentials configured correctly.\n{}".format(
                json.dumps(conn.result))
            demisto.info(message)
            return_error(message)
            return
    except Exception as e:
        exc_msg = str(e)
        demisto.info("Failed bind to: {}:{}. {}: {}".format(SERVER_IP, PORT, type(e), exc_msg
                     + "\nTrace:\n{}".format(traceback.format_exc())))
        message = "Failed to access LDAP server. Please validate the server host and port are configured correctly"
        if 'ssl wrapping error' in exc_msg:
            message = "Failed to access LDAP server. SSL error."
            if not UNSECURE:
                message += ' Try using: "Trust any certificate" option.'
        demisto.info(message)
        return_error(message)
        return

    demisto.info('Established connection with AD LDAP server')

    if not base_dn_verified(DEFAULT_BASE_DN):
        message = "Failed to verify the base DN configured for the instance.\n" \
            "Last connection result: {}\n" \
            "Last error from LDAP server: {}".format(json.dumps(conn.result), json.dumps(conn.last_error))
        demisto.info(message)
        return_error(message)
        return

    demisto.info('Verfied base DN "{}"'.format(DEFAULT_BASE_DN))

    ''' COMMAND EXECUTION '''

    try:
        if demisto.command() == 'test-module':
            if conn.user == '':
                # Empty response means you have no authentication status on the server, so you are an anonymous user.
                raise Exception("Failed to authenticate user")
            demisto.results('ok')

        if demisto.command() == 'ad-search':
            free_search(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE)

        if demisto.command() == 'ad-expire-password':
            expire_user_password(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-set-new-password':
            set_user_password(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-unlock-account':
            unlock_account(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-disable-account':
            disable_user(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-enable-account':
            enable_user(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-remove-from-group':
            remove_member_from_group(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-add-to-group':
            add_member_to_group(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-create-user':
            create_user()

        if demisto.command() == 'ad-delete-user':
            delete_user()

        if demisto.command() == 'ad-update-user':
            update_user(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-modify-computer-ou':
            modify_computer_ou(DEFAULT_BASE_DN)

        if demisto.command() == 'ad-create-contact':
            create_contact()

        if demisto.command() == 'ad-update-contact':
            update_contact()

        if demisto.command() == 'ad-get-user':
            search_users(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE)

        if demisto.command() == 'ad-get-computer':
            search_computers(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE)

        if demisto.command() == 'ad-get-group-members':
            search_group_members(DEFAULT_BASE_DN, DEFAULT_PAGE_SIZE)

    except Exception as e:
        message = "{}\nLast connection result: {}\nLast error from LDAP server: {}".format(
            str(e), json.dumps(conn.result), conn.last_error)
        demisto.info(message)
        return_error(message)
        return
    finally:
        # disconnect and close the connection
        conn.unbind()