import logging

logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s', )


class SnortRule(object):
    def __init__(self, **kwargs):
        # Rule Headers
        self.action = kwargs.get('action', 'alert')
        self.protocol = kwargs.get('protocol', 'tcp')
        self.src_ip = kwargs.get('src_ip', 'any')
        self.src_port = str(kwargs.get('src_port', 'any'))
        self.dst_ip = kwargs.get('dst_ip', 'any')
        self.dst_port = str(kwargs.get('dst_port', 'any'))

        # General Rule
        self.msg = kwargs.get('msg')
        self.ref = kwargs.get('reference')
        self.sid = kwargs.get('sid')
        self.gid = kwargs.get('gid')
        self.rev = kwargs.get('rev')
        self.classtype = kwargs.get('classtype')
        self.priority = kwargs.get('priority')
        self.metadata = kwargs.get('metadata')

        # Payload Dection Rule
        self.content = kwargs.get('content')
        self.uricontent = kwargs.get('uricontent')
        self.nocase = kwargs.get('nocase', 'nocase')
        self.payload_options = [self.content, self.uricontent, self.nocase]

    def __rule_header(self):
        '''Generate snort rule header'''
        header = [self.action, self.protocol, self.src_ip,
                  self.src_port, '->', self.dst_ip, self.dst_port]
        return ' '.join(header)

    def __rule_general(self):
        '''Generate snort general rule options'''
        references = self.__slice_multiple('reference', self.ref)

        rest_general = ['msg:{message}'.format(message=self.msg),
                        'sid:{sid}'.format(sid=self.sid),
                        'gid:{gid}'.format(gid=self.gid),
                        'rev:{rev}'.format(rev=self.rev),
                        'classtype:{clstype}'.format(clstype=self.classtype),
                        'priority:{priority}'.format(priority=self.priority),
                        'metadata:{metadata}'.format(metadata=self.metadata)]
        general = rest_general + references
        general = self.__clean_none(general)
        return '; '.join(general)

    def __rule_payload(self):
        '''Generate snort payload detection rule options'''
        contents = self.__slice_multiple('content', self.content)
        rest_payload = ['uricontent:{uri}'.format(uri=self.uricontent),
                        '{nocase}'.format(nocase=self.nocase)]
        payload = contents + rest_payload
        payload = self.__clean_none(payload)
        return '; '.join(payload)

    def __rule_non_payload(self):
        '''Generate snort non-payload detection rule options'''
        pass

    def __clean_none(self, option_list):
        '''Clean the None in the list'''
        update = []
        for option in option_list:
            if "None" not in option:
                update.append(option)
        return update

    def __rule_options(self):
        '''Generate rule options'''
        general = self.__rule_general()
        payload = self.__rule_payload()
        return "({general}; {payload};)".format(general=general,
                                                payload=payload)

    def __slice_multiple(self, tag, data):
        '''Slice the multiple item'''
        if data is None:
            return []
        elif type(data) is not list:
            logging.info("[TypeError] %s must be a list" % tag)
            return []
        else:
            sliced = []
            for item in data:
                sliced.append('{tag}:{item}'.format(tag=tag, item=item))
            return sliced

    def generate(self):
        '''Generate complete snort rule'''
        header = self.__rule_header()
        options = self.__rule_options()
        return "{header}{options}".format(header=header, options=options)


if __name__ == "__main__":

    malicious_pattern = {
        'dst_port': 21,
        'msg': '"Trojan.VB.Gen"',
        'content': ['"|2f 70 6b 69 2f 63 72 6c 2f 70 72 6f|"', '"hello world"'],
        'uricontent': '"/DirectDownloaderInstaller.exe"',
        'reference': ['md5,c1920c396043d109af6d8315cc66ba44',
                      'email,rules@anti-botnet.edu.tw'],
        'sid': 1000001}

    rule = SnortRule(**malicious_pattern)
    print rule.generate()

Add a class for snort rule generate