~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to bin/ivle-buildjail

  • Committer: William Grant
  • Date: 2009-12-10 09:47:38 UTC
  • Revision ID: grantw@unimelb.edu.au-20091210094738-pa4yrieyb9ynigej
Clean up and correct the admin scripts documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
import optparse
20
20
import os
 
21
import stat
21
22
import sys
22
23
import shutil
23
24
 
24
 
import ivle.conf
25
25
import ivle.config
26
26
import ivle.jailbuilder.debian
27
27
 
 
28
class UnsafeJail(Exception):
 
29
    pass
 
30
 
28
31
usage = """usage: %prog [options]
29
32
(requires root)
30
33
Builds or updates the base IVLE jail."""
31
34
 
 
35
# Requires root
 
36
if os.getuid() != 0:
 
37
    print >> sys.stderr, "This script requires root privlages to run"
 
38
    sys.exit(1)
 
39
 
32
40
conf = ivle.config.Config()
33
 
build_path = ivle.conf.jail_system_build
 
41
build_path = conf['paths']['jails']['template_build']
34
42
 
35
43
# Parse arguments
36
44
parser = optparse.OptionParser(usage)
43
51
    help='''Apply any package updates in the jail.''')
44
52
parser.add_option("-m", "--mirror",
45
53
    action="store", dest="apt_mirror",
46
 
    help="Sets the apt mirror.", default="http://archive.ubuntu.com/ubuntu")
 
54
    help="Sets the apt mirror.", default=conf['jail']['mirror'])
 
55
parser.add_option("--python-site-packages",
 
56
    action="store", dest="python_site_packages",
 
57
    help="Path to Python site packages directory inside the jail.",
 
58
    default=None)
47
59
(options, args) = parser.parse_args(sys.argv)
48
60
 
49
61
if os.geteuid() != 0:
54
66
    print >> sys.stderr, "No jail exists -- please rerun with -r."
55
67
    sys.exit(1)
56
68
 
 
69
if (options.python_site_packages is not None and
 
70
    options.python_site_packages[:1] not in (os.path.sep, os.path.altsep)):
 
71
    print >> sys.stderr, "python-site-packages must be an absolute path."
 
72
    sys.exit(1)
 
73
 
57
74
if options.recreate:
58
75
    options.upgrade = True
59
76
 
67
84
              build_path, mirror=options.apt_mirror)
68
85
 
69
86
    ivle.jailbuilder.debian.apt_update_cache(build_path)
 
87
    # Minimal required packages
70
88
    ivle.jailbuilder.debian.apt_install(build_path,
71
 
                        ['python2.5', 'python-cjson', 'python-svn'])
 
89
            ['python2.5', 'python-cjson', 'python-svn', 'python-configobj'])
72
90
 
73
91
    ivle.jailbuilder.debian.apt_clean(build_path)
74
92
 
102
120
 
103
121
if conf['jail']['devmode']:
104
122
    # Copy all console and operating system files into the jail
105
 
    services_path = os.path.join(ivle.conf.share_path, 'services')
 
123
    services_path = os.path.join(conf['paths']['share'], 'services')
106
124
    jail_services_path = os.path.join(build_path, services_path[1:])
107
125
    if os.path.exists(jail_services_path):
108
126
        shutil.rmtree(jail_services_path)
110
128
 
111
129
    # Also copy the IVLE lib directory into the jail
112
130
    # This is necessary for running certain services
113
 
    ivle_site_packages = os.path.join(ivle.conf.python_site_packages, 'ivle')
114
 
    jail_site_packages = os.path.join(build_path, ivle_site_packages[1:])
 
131
 
 
132
    # ivle_site_packages is the IVLE install location outside the jail
 
133
    ivle_site_packages = os.path.dirname(ivle.__file__)
 
134
 
 
135
    if options.python_site_packages is None:
 
136
        # Get the site packages from the IVLE install location *OUTSIDE* the
 
137
        # jail. Warning! This only works if you have the same Python site
 
138
        # packages directory inside and out (ie. same Python version).
 
139
        # If not, you should use --python-site-packages.
 
140
        jail_site_packages = os.path.join(build_path, ivle_site_packages[1:])
 
141
    else:
 
142
        # User-specified site packages
 
143
        jail_site_packages = os.path.join(build_path,
 
144
                                options.python_site_packages[1:], "ivle")
115
145
    if os.path.exists(jail_site_packages):
116
146
        shutil.rmtree(jail_site_packages)
117
147
    shutil.copytree(ivle_site_packages, jail_site_packages)
118
148
 
119
 
    # IMPORTANT: ivle/conf/conf.py contains details which could compromise security
120
 
    # if left in the jail (such as the DB password). We delete it now! It would be
121
 
    # shadowed by the per-user conf.py anyway, but it's best to be safe.
122
 
    os.unlink(os.path.join(jail_site_packages, 'conf/conf.py'))
123
 
    # XXX: Shouldn't copy the compiled files at all, but compile them in the jail!
124
 
    os.unlink(os.path.join(jail_site_packages, 'conf/conf.pyc'))
125
 
 
 
149
# Make /tmp and /var/lock un-world-writable. /tmp will be mounted over,
 
150
# and /var/{lock,tmp} should die.
 
151
for path in ('tmp', 'var/lock', 'var/tmp'):
 
152
    path = os.path.join(build_path, path)
 
153
    os.chmod(path, os.stat(path).st_mode & ~stat.S_IWOTH)
 
154
 
 
155
# Verify that nothing in the jail is world-writable.
 
156
# We don't want students to write into places that others can see.
 
157
try:
 
158
    for path, dirs, files in os.walk(build_path):
 
159
        for dname in dirs:
 
160
            d = os.path.join(path, dname)
 
161
            if os.path.islink(d):
 
162
                continue
 
163
            if os.stat(d).st_mode & stat.S_IWOTH:
 
164
                raise UnsafeJail(d)
 
165
 
 
166
        for fname in files:
 
167
            f = os.path.join(path, fname)
 
168
            if os.path.islink(f):
 
169
                continue
 
170
            if os.stat(f).st_mode & stat.S_IWOTH:
 
171
                if (os.path.dirname(f) == os.path.join(build_path, 'dev') and
 
172
                    os.path.basename(f) in ('ptmx', 'null', 'tty', 'full', 'zero',
 
173
                                            'random', 'urandom')
 
174
                    ):
 
175
                    continue
 
176
                raise UnsafeJail(f)
 
177
except UnsafeJail, e:
 
178
    print >> sys.stderr,"""Error: Jail contains world writable path: '%s'.
 
179
This is a security vulnerability as jail template contents are shared between 
 
180
users. Please either make this path world unwriteable or remove it from the 
 
181
jail."""%str(e)
 
182
    sys.exit(1)
 
183
 
 
184
# Copy jail template build to actual jail template
 
185
template_path = conf['paths']['jails']['template']
126
186
if os.spawnvp(os.P_WAIT, 'rsync', ['rsync', '-a', '--delete',
127
 
              build_path + '/', ivle.conf.jail_system]) != 0:
 
187
              build_path + '/', template_path]) != 0:
128
188
    print >> sys.stderr, "Jail copying failed."
129
189
    sys.exit(1)
130
190
 
 
191
# Now mangle things a bit, so we can bind-mount the user bits in.
 
192
# /etc/passwd and /etc/ivle/ivle.conf need to be symlinks to somewhere in /home
 
193
 
 
194
os.rename(os.path.join(template_path, 'etc/passwd'),
 
195
          os.path.join(template_path, 'home/.passwd')
 
196
          )
 
197
os.symlink('../home/.passwd', os.path.join(template_path, 'etc/passwd'))
 
198
 
 
199
os.makedirs(os.path.join(template_path, "etc/ivle"))
 
200
os.symlink('../../home/.ivle.conf',
 
201
           os.path.join(template_path, "etc/ivle/ivle.conf"))