1# Copyright (C) 2017 Open Information Security Foundation
2# Copyright (c) 2013 Jason Ish
3#
4# You can copy, redistribute or modify this Program under the terms of
5# the GNU General Public License version 2 as published by the Free
6# Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# version 2 along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16# 02110-1301, USA.
17
18""" Module for utility functions that don't really fit anywhere else. """
19
20import hashlib
21import tempfile
22import atexit
23import shutil
24import zipfile
25
26def md5_hexdigest(filename):
27    """ Compute the MD5 checksum for the contents of the provided filename.
28
29    :param filename: Filename to computer MD5 checksum of.
30
31    :returns: A string representing the hex value of the computed MD5.
32    """
33    return hashlib.md5(open(filename).read().encode()).hexdigest()
34
35def mktempdir(delete_on_exit=True):
36    """ Create a temporary directory that is removed on exit. """
37    tmpdir = tempfile.mkdtemp("suricata-update")
38    if delete_on_exit:
39        atexit.register(shutil.rmtree, tmpdir, ignore_errors=True)
40    return tmpdir
41
42class ZipArchiveReader:
43
44    def __init__(self, zipfile):
45        self.zipfile = zipfile
46        self.names = self.zipfile.namelist()
47
48    def __iter__(self):
49        return self
50
51    def __enter__(self):
52        return self
53
54    def __exit__(self, type, value, traceback):
55        self.zipfile.close()
56
57    def next(self):
58        if self.names:
59            name = self.names.pop(0)
60            if name.endswith("/"):
61                # Is a directory, ignore
62                return self.next()
63            return name
64        raise StopIteration
65
66    def open(self, name):
67        return self.zipfile.open(name)
68
69    def read(self, name):
70        return self.zipfile.read(name)
71
72    @classmethod
73    def from_fileobj(cls, fileobj):
74        zf = zipfile.ZipFile(fileobj)
75        return cls(zf)
76
77GREEN = "\x1b[32m"
78BLUE = "\x1b[34m"
79REDB = "\x1b[1;31m"
80YELLOW = "\x1b[33m"
81RED = "\x1b[31m"
82YELLOWB = "\x1b[1;33m"
83ORANGE = "\x1b[38;5;208m"
84BRIGHT_MAGENTA = "\x1b[1;35m"
85BRIGHT_CYAN = "\x1b[1;36m"
86RESET = "\x1b[0m"
87
88def blue(msg):
89    return "%s%s%s" % (BLUE, msg, RESET)
90
91def bright_magenta(msg):
92    return "%s%s%s" % (BRIGHT_MAGENTA, msg, RESET)
93
94def bright_cyan(msg):
95    return "%s%s%s" % (BRIGHT_CYAN, msg, RESET)
96
97def orange(msg):
98    return "%s%s%s" % (ORANGE, msg, RESET)
99