# SPDX-FileCopyrightText: 2015 Sebastian Wagner
#
# SPDX-License-Identifier: AGPL-3.0-or-later

# -*- coding: utf-8 -*-
import os
import unittest

import intelmq.lib.test as test
import intelmq.lib.utils as utils
from intelmq.bots.parsers.spamhaus.parser_cert import SpamhausCERTParserBot


with open(os.path.join(os.path.dirname(__file__), 'cert.txt')) as handle:
    FILE = handle.read()
FILE_LINES = FILE.splitlines()

EXAMPLE_REPORT = {"feed.url": "https://portal.spamhaus.org/cert/api.php?cert="
                              "<CERTNAME>&key=<APIKEY>",
                  'raw': utils.base64_encode(FILE),
                  "__type": "Report",
                  "feed.name": "Spamhaus Cert",
                  "time.observation": "2015-01-01T00:00:00+00:00",
                  }
EVENT_TEMPL = {"feed.url": "https://portal.spamhaus.org/cert/api.php?cert="
                           "<CERTNAME>&",
               "feed.name": "Spamhaus Cert",
               "__type": "Event",
               "time.observation": "2015-01-01T00:00:00+00:00",
               }
EXAMPLE_EVENTS_PARTS = [{'source.ip': '109.126.64.2',
                         'source.asn': 12635,
                         'classification.type': 'infected-system',
                         'time.source': '2015-08-31T08:16:10+00:00',
                         'malware.name': 'asprox',
                         'destination.port': 25,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '109.90.233.19',
                         'source.asn': 6830,
                         'classification.type': 'infected-system',
                         'time.source': '2015-08-31T08:05:51+00:00',
                         'malware.name': 'patcher',
                         'destination.port': 80,
                         'destination.fqdn': 'dxxt.sinkhole.dk',
                         'destination.ip': '212.227.20.19',
                         'extra.source.local_port': 1036,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '109.91.0.227',
                         'source.asn': 6830,
                         'classification.type': 'infected-system',
                         'time.source': '2015-08-31T09:00:57+00:00',
                         'malware.name': 'conficker',
                         'destination.port': 80,
                         'destination.ip': '216.66.15.109',
                         'extra.source.local_port': 1430,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '111.111.111.183',
                         'source.asn': 11178,
                         'classification.identifier': 'mirai',
                         'classification.type': 'infected-system',
                         'time.source': '2016-08-13T17:58:59+00:00',
                         'malware.name': 'mirai',
                         'source.geolocation.cc': 'LV',
                         },
                        {'source.ip': '198.51.100.54',
                         'source.asn': 8559,
                         'time.source': '2018-03-03T13:41:36+00:00',
                         'classification.type': 'scanner',
                         'classification.identifier': 'rdp',
                         'protocol.application': 'rdp',
                         'destination.port': 3389,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '198.51.100.54',
                         'source.asn': 8559,
                         'time.source': '2018-03-03T13:41:36+00:00',
                         'classification.type': 'vulnerable-system',
                         'classification.identifier': 'openrelay',
                         'protocol.application': 'smtp',
                         'destination.port': 25,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '245.16.92.48',
                         'source.asn': 64496,
                         'time.source': '2018-03-20T13:29:12+00:00',
                         'destination.ip': '249.145.142.15',
                         'destination.port': 22,
                         'classification.type': 'brute-force',
                         'classification.identifier': 'ssh',
                         'source.geolocation.cc': 'AT',
                         'protocol.application': 'ssh',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '245.16.92.48',
                         'source.asn': 64496,
                         'time.source': '2018-03-20T13:29:12+00:00',
                         'destination.ip': '249.145.142.15',
                         'destination.port': 23,
                         'classification.type': 'brute-force',
                         'classification.identifier': 'telnet',
                         'source.geolocation.cc': 'AT',
                         'protocol.application': 'telnet',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '172.20.148.81',
                         'source.asn': 64496,
                         'time.source': '2018-03-17T13:00:32+00:00',
                         'destination.port': 80,
                         'classification.type': 'scanner',
                         'classification.identifier': 'wordpress-vulnerabilities',
                         'event_description.text': 'scanning for wordpress vulnerabilities',
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'protocol.application': 'http',
                         },
                        {'source.ip': '172.20.148.81',
                         'source.asn': 64496,
                         'time.source': '2018-03-17T13:00:32+00:00',
                         'destination.port': 80,
                         'classification.type': 'scanner',
                         'classification.identifier': 'wordpress-login',
                         'event_description.text': 'scanning for wordpress login pages',
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'protocol.application': 'http',
                         },
                        {'source.ip': '109.91.0.227',
                         'source.asn': 64496,
                         'classification.type': 'infected-system',
                         'time.source': '2015-08-31T09:00:57+00:00',
                         'malware.name': 's_other',
                         'destination.port': 80,
                         'destination.ip': '216.66.15.109',
                         'extra.source.local_port': 1430,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                         {'classification.type': 'spam',
                         'classification.identifier': 'spamlink',
                         'malware.name': 'darkmailer2',
                         'malware.version': '1660',
                         'source.url': 'http://example.com/',
                         'protocol.transport': 'tcp',
                         'source.asn': 64496,
                         'source.geolocation.cc': 'AT',
                         'source.ip': '192.168.46.8',
                         'event_description.text': 'The URL appeared in a spam email sent by extra.spam_ip.',
                         'time.source': '2018-04-08T13:05:08+00:00',
                         'extra.spam_ip': "192.168.46.8",
                         },
                        {'source.ip': '198.51.100.54',
                         'source.asn': 64496,
                         'time.source': '2018-05-31T09:40:54+00:00',
                         'classification.type': 'brute-force',
                         'classification.identifier': 'smtp',
                         'protocol.application': 'smtp',
                         'destination.port': 25,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         },
                        {'source.ip': '10.56.59.94',
                         'source.asn': 65551,
                         'time.source': '2018-06-10T19:22:42+00:00',
                         'classification.type': 'brute-force',
                         'classification.identifier': 'imap',
                         'protocol.application': 'imap',
                         'destination.port': 993,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'extra.source.local_port': 64954,
                         },
                        {'source.ip': '10.56.59.94',
                         'source.asn': 65551,
                         'time.source': '2018-05-26T05:59:11+00:00',
                         'classification.type': 'other',
                         'classification.identifier': 'proxyget',
                         'destination.ip': '192.168.255.154',
                         'destination.port': 8080,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'extra.source.local_port': 40625,
                         'event_description.text': 'The malicious client used a honeypot as proxy.',
                         },
                        {'source.ip': '10.56.59.94',
                         'source.asn': 65551,
                         'time.source': '2017-09-29T14:48:17+00:00',
                         'classification.type': 'scanner',
                         'classification.identifier': 'telnet',
                         'protocol.application': 'telnet',
                         'destination.ip': '198.18.159.123',
                         'destination.port': 23,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'extra.source.local_port': 57090,
                         'event_description.text': 'The possibly infected IoT device scanned for '
                                                   'other vulnerable IoT devices.',
                         },
                        {'source.ip': '203.0.113.81',
                         'source.asn': 65551,
                         'time.source': '2018-07-05T11:25:32+00:00',
                         'classification.type': 'brute-force',
                         'classification.identifier': 'authentication-spoof',
                         'protocol.application': 'smtp',
                         'destination.port': 25,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'event_description.text': 'The device spoofed SMTP authentication with a bad '
                                                   'EHLO.',
                         },
                        {'source.ip': '172.20.148.82',
                         'source.asn': 65551,
                         'time.source': '2019-04-23T06:38:02+00:00',
                         'classification.type': 'spam',
                         'classification.identifier': 'extortion',
                         'protocol.application': 'smtp',
                         'destination.port': 25,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'event_description.text': 'This device sent extortion mails.',
                         },
                        {'source.ip': '172.20.148.82',
                         'source.asn': 65551,
                         'time.source': '2019-10-13T08:39:35+00:00',
                         'classification.type': 'spam',
                         'classification.identifier': 'spam',
                         'protocol.application': 'smtp',
                         'destination.port': 25,
                         'source.geolocation.cc': 'AT',
                         'protocol.transport': 'tcp',
                         'event_description.text': 'This device is sending spam as part of a botnet. See abuseat.org for more details.',
                         'event_description.url': 'https://www.abuseat.org/lookup.cgi',
                         'feed.documentation': 'https://www.abuseat.org/lookup.cgi',
                         },
                        ]


class TestSpamhausCERTParserBot(test.BotTestCase, unittest.TestCase):
    """
    A TestCase for SpamhausCERTParserBot.
    """

    @classmethod
    def set_bot(cls):
        cls.bot_reference = SpamhausCERTParserBot
        cls.default_input_message = EXAMPLE_REPORT

    def test_events(self):
        """ Test if correct Events have been produced. """
        self.run_bot()
        for position, event in enumerate(EXAMPLE_EVENTS_PARTS):
            event_ = EVENT_TEMPL.copy()
            event_.update(event)
            event_['raw'] = utils.base64_encode('\n'.join((FILE_LINES[0],
                                                           FILE_LINES[1+position])))
            self.assertMessageEqual(position, event_)
        self.assertOutputQueueLen(len(EXAMPLE_EVENTS_PARTS))


if __name__ == '__main__':  # pragma: no cover
    unittest.main()
