Statistics
| Branch: | Tag: | Revision:

root / image_creator / os_type / unix.py @ f165adc0

History | View | Annotate | Download (6.3 kB)

1 ae48a082 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
2 ae48a082 Nikos Skalkotos
#
3 ae48a082 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
4 ae48a082 Nikos Skalkotos
# without modification, are permitted provided that the following
5 ae48a082 Nikos Skalkotos
# conditions are met:
6 ae48a082 Nikos Skalkotos
#
7 ae48a082 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
8 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
9 ae48a082 Nikos Skalkotos
#      disclaimer.
10 ae48a082 Nikos Skalkotos
#
11 ae48a082 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
12 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
13 ae48a082 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
14 ae48a082 Nikos Skalkotos
#      provided with the distribution.
15 ae48a082 Nikos Skalkotos
#
16 ae48a082 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 ae48a082 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 ae48a082 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 ae48a082 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 ae48a082 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 ae48a082 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 ae48a082 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 ae48a082 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 ae48a082 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 ae48a082 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 ae48a082 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 ae48a082 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
28 ae48a082 Nikos Skalkotos
#
29 ae48a082 Nikos Skalkotos
# The views and conclusions contained in the software and
30 ae48a082 Nikos Skalkotos
# documentation are those of the authors and should not be
31 ae48a082 Nikos Skalkotos
# interpreted as representing official policies, either expressed
32 ae48a082 Nikos Skalkotos
# or implied, of GRNET S.A.
33 aa2062ba Nikos Skalkotos
34 aa2062ba Nikos Skalkotos
import re
35 8c574358 Nikos Skalkotos
import sys
36 aa2062ba Nikos Skalkotos
37 f165adc0 Nikos Skalkotos
from image_creator.os_type import OSBase, sysprep
38 979096dd Nikos Skalkotos
from image_creator.util import warn, output
39 aa2062ba Nikos Skalkotos
40 8c574358 Nikos Skalkotos
41 aa2062ba Nikos Skalkotos
class Unix(OSBase):
42 0d5a999d Nikos Skalkotos
43 f8119e65 Nikos Skalkotos
    sensitive_userdata = [
44 f8119e65 Nikos Skalkotos
        '.bash_history',
45 f8119e65 Nikos Skalkotos
        '.gnupg',
46 f8119e65 Nikos Skalkotos
        '.ssh',
47 f8119e65 Nikos Skalkotos
        '.mozilla',
48 f8119e65 Nikos Skalkotos
        '.thunderbird'
49 f8119e65 Nikos Skalkotos
    ]
50 0d5a999d Nikos Skalkotos
51 aa2062ba Nikos Skalkotos
    def get_metadata(self):
52 aa2062ba Nikos Skalkotos
        meta = super(Unix, self).get_metadata()
53 aa2062ba Nikos Skalkotos
        meta["USERS"] = " ".join(self.get_passworded_users())
54 aa2062ba Nikos Skalkotos
        return meta
55 aa2062ba Nikos Skalkotos
56 aa2062ba Nikos Skalkotos
    def get_passworded_users(self):
57 aa2062ba Nikos Skalkotos
        users = []
58 aa2062ba Nikos Skalkotos
        regexp = re.compile('(\S+):((?:!\S+)|(?:[^!*]\S+)|):(?:\S*:){6}')
59 aa2062ba Nikos Skalkotos
60 36e348b6 Nikos Skalkotos
        for line in self.g.cat('/etc/shadow').splitlines():
61 aa2062ba Nikos Skalkotos
            match = regexp.match(line)
62 aa2062ba Nikos Skalkotos
            if not match:
63 aa2062ba Nikos Skalkotos
                continue
64 aa2062ba Nikos Skalkotos
65 aa2062ba Nikos Skalkotos
            user, passwd = match.groups()
66 aa2062ba Nikos Skalkotos
            if len(passwd) > 0 and passwd[0] == '!':
67 22a6d232 Nikos Skalkotos
                warn("Ignoring locked %s account." % user)
68 aa2062ba Nikos Skalkotos
            else:
69 aa2062ba Nikos Skalkotos
                users.append(user)
70 aa2062ba Nikos Skalkotos
71 aa2062ba Nikos Skalkotos
        return users
72 aa2062ba Nikos Skalkotos
73 f165adc0 Nikos Skalkotos
    @sysprep(enabled=False)
74 f165adc0 Nikos Skalkotos
    def remove_user_accounts(self, print_header=True):
75 a9c9d939 Nikos Skalkotos
        """Remove all user account with id more than 1000"""
76 a9c9d939 Nikos Skalkotos
77 a9c9d939 Nikos Skalkotos
        if print_header:
78 a9c9d939 Nikos Skalkotos
            output('Removing all user accounts with id greater than 1000')
79 a9c9d939 Nikos Skalkotos
80 a9c9d939 Nikos Skalkotos
        # Remove users from /etc/passwd
81 a9c9d939 Nikos Skalkotos
        passwd = []
82 a9c9d939 Nikos Skalkotos
        removed_users = {}
83 a9c9d939 Nikos Skalkotos
        for line in self.g.cat('/etc/passwd').splitlines():
84 a9c9d939 Nikos Skalkotos
            fields = line.split(':')
85 a9c9d939 Nikos Skalkotos
            if int(fields[2]) > 1000:
86 a9c9d939 Nikos Skalkotos
                removed_users[fields[0]] = fields
87 a9c9d939 Nikos Skalkotos
            else:
88 a9c9d939 Nikos Skalkotos
                passwd.append(':'.join(fields))
89 a9c9d939 Nikos Skalkotos
90 a9c9d939 Nikos Skalkotos
        self.g.write('/etc/passwd', '\n'.join(passwd) + '\n')
91 a9c9d939 Nikos Skalkotos
92 a9c9d939 Nikos Skalkotos
        # Remove the corresponding /etc/shadow entries
93 a9c9d939 Nikos Skalkotos
        shadow = []
94 a9c9d939 Nikos Skalkotos
        for line in self.g.cat('/etc/shadow').splitlines():
95 a9c9d939 Nikos Skalkotos
            fields = line.split(':')
96 a9c9d939 Nikos Skalkotos
            if fields[0] not in removed_users:
97 a9c9d939 Nikos Skalkotos
                shadow.append(':'.join(fields))
98 a9c9d939 Nikos Skalkotos
99 a9c9d939 Nikos Skalkotos
        self.g.write('/etc/shadow', "\n".join(shadow) + '\n')
100 a9c9d939 Nikos Skalkotos
101 a9c9d939 Nikos Skalkotos
        # Remove the corresponding /etc/group entries
102 a9c9d939 Nikos Skalkotos
        group = []
103 a9c9d939 Nikos Skalkotos
        for line in self.g.cat('/etc/group').splitlines():
104 a9c9d939 Nikos Skalkotos
            fields = line.split(':')
105 a9c9d939 Nikos Skalkotos
            # Remove groups tha have the same name as the removed users
106 a9c9d939 Nikos Skalkotos
            if fields[0] not in removed_users:
107 a9c9d939 Nikos Skalkotos
                group.append(':'.join(fields))
108 a9c9d939 Nikos Skalkotos
109 a9c9d939 Nikos Skalkotos
        self.g.write('/etc/group', '\n'.join(group) + '\n')
110 4cab6d62 Nikos Skalkotos
111 a9c9d939 Nikos Skalkotos
        # Remove home directories
112 a9c9d939 Nikos Skalkotos
        for home in [field[5] for field in removed_users.values()]:
113 a9c9d939 Nikos Skalkotos
            if self.g.is_dir(home) and home.startswith('/home/'):
114 a9c9d939 Nikos Skalkotos
                self.g.rm_rf(home)
115 a9c9d939 Nikos Skalkotos
116 f165adc0 Nikos Skalkotos
    @sysprep()
117 f165adc0 Nikos Skalkotos
    def cleanup_passwords(self, print_header=True):
118 51fab9c9 Nikos Skalkotos
        """Remove all passwords and lock all user accounts"""
119 51fab9c9 Nikos Skalkotos
120 51fab9c9 Nikos Skalkotos
        if print_header:
121 51fab9c9 Nikos Skalkotos
            output('Cleaning up passwords & locking all user accounts')
122 51fab9c9 Nikos Skalkotos
123 51fab9c9 Nikos Skalkotos
        shadow = []
124 51fab9c9 Nikos Skalkotos
125 51fab9c9 Nikos Skalkotos
        for line in self.g.cat('/etc/shadow').splitlines():
126 51fab9c9 Nikos Skalkotos
            fields = line.split(':')
127 51fab9c9 Nikos Skalkotos
            if fields[1] not in ('*', '!'):
128 51fab9c9 Nikos Skalkotos
                fields[1] = '!'
129 51fab9c9 Nikos Skalkotos
130 51fab9c9 Nikos Skalkotos
            shadow.append(":".join(fields))
131 51fab9c9 Nikos Skalkotos
132 a9c9d939 Nikos Skalkotos
        self.g.write('/etc/shadow', "\n".join(shadow) + '\n')
133 51fab9c9 Nikos Skalkotos
134 f165adc0 Nikos Skalkotos
    @sysprep()
135 f165adc0 Nikos Skalkotos
    def cleanup_cache(self, print_header=True):
136 f8119e65 Nikos Skalkotos
        """Remove all regular files under /var/cache"""
137 22a6d232 Nikos Skalkotos
138 3f70f242 Nikos Skalkotos
        if print_header:
139 979096dd Nikos Skalkotos
            output('Removing files under /var/cache')
140 22a6d232 Nikos Skalkotos
141 c16922f7 Nikos Skalkotos
        self.foreach_file('/var/cache', self.g.rm, ftype='r')
142 0d5a999d Nikos Skalkotos
143 f165adc0 Nikos Skalkotos
    @sysprep()
144 f165adc0 Nikos Skalkotos
    def cleanup_tmp(self, print_header=True):
145 f8119e65 Nikos Skalkotos
        """Remove all files under /tmp and /var/tmp"""
146 22a6d232 Nikos Skalkotos
147 3f70f242 Nikos Skalkotos
        if print_header:
148 979096dd Nikos Skalkotos
            output('Removing files under /tmp and /var/tmp')
149 22a6d232 Nikos Skalkotos
150 8c574358 Nikos Skalkotos
        self.foreach_file('/tmp', self.g.rm_rf, maxdepth=1)
151 9297c398 Nikos Skalkotos
        self.foreach_file('/var/tmp', self.g.rm_rf, maxdepth=1)
152 0d5a999d Nikos Skalkotos
153 f165adc0 Nikos Skalkotos
    @sysprep()
154 f165adc0 Nikos Skalkotos
    def cleanup_log(self, print_header=True):
155 f8119e65 Nikos Skalkotos
        """Empty all files under /var/log"""
156 22a6d232 Nikos Skalkotos
157 3f70f242 Nikos Skalkotos
        if print_header:
158 979096dd Nikos Skalkotos
            output('Emptying all files under /var/log')
159 22a6d232 Nikos Skalkotos
160 8c574358 Nikos Skalkotos
        self.foreach_file('/var/log', self.g.truncate, ftype='r')
161 0d5a999d Nikos Skalkotos
162 f165adc0 Nikos Skalkotos
    @sysprep(enabled=False)
163 f165adc0 Nikos Skalkotos
    def cleanup_mail(self, print_header=True):
164 f8119e65 Nikos Skalkotos
        """Remove all files under /var/mail and /var/spool/mail"""
165 22a6d232 Nikos Skalkotos
166 3f70f242 Nikos Skalkotos
        if print_header:
167 979096dd Nikos Skalkotos
            output('Removing files under /var/mail and /var/spool/mail')
168 22a6d232 Nikos Skalkotos
169 f8119e65 Nikos Skalkotos
        self.foreach_file('/var/spool/mail', self.g.rm_rf, maxdepth=1)
170 f8119e65 Nikos Skalkotos
        self.foreach_file('/var/mail', self.g.rm_rf, maxdepth=1)
171 9297c398 Nikos Skalkotos
172 f165adc0 Nikos Skalkotos
    @sysprep()
173 f165adc0 Nikos Skalkotos
    def cleanup_userdata(self, print_header=True):
174 f8119e65 Nikos Skalkotos
        """Delete sensitive userdata"""
175 22a6d232 Nikos Skalkotos
176 0d5a999d Nikos Skalkotos
        homedirs = ['/root'] + self.ls('/home/')
177 0d5a999d Nikos Skalkotos
178 3f70f242 Nikos Skalkotos
        if print_header:
179 979096dd Nikos Skalkotos
            output('Removing sensitive user data under %s' % " ".
180 979096dd Nikos Skalkotos
                                                        join(homedirs))
181 3f70f242 Nikos Skalkotos
182 0d5a999d Nikos Skalkotos
        for homedir in homedirs:
183 0d5a999d Nikos Skalkotos
            for data in self.sensitive_userdata:
184 0d5a999d Nikos Skalkotos
                fname = "%s/%s" % (homedir, data)
185 0d5a999d Nikos Skalkotos
                if self.g.is_file(fname):
186 0d5a999d Nikos Skalkotos
                    self.g.scrub_file(fname)
187 aa2062ba Nikos Skalkotos
188 aa2062ba Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :