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

« back to all changes in this revision

Viewing changes to bin/ivle-buildjail

  • Committer: Matt Giuca
  • Date: 2010-02-04 05:32:04 UTC
  • Revision ID: matt.giuca@gmail.com-20100204053204-oqp66c3o3eqngusw
Sample database: Added a sample worksheet.

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 used when recreating the jail.")
 
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:
 
75
    options.upgrade = True
 
76
 
58
77
    # Create the jail and its subdirectories
59
78
    # Note: Other subdirs will be made by copying files
60
79
    if options.apt_mirror is not None:
64
83
    ivle.jailbuilder.debian.debootstrap_create_jail(conf['jail']['suite'],
65
84
              build_path, mirror=options.apt_mirror)
66
85
 
 
86
    ivle.jailbuilder.debian.apt_update_cache(build_path)
 
87
    # Minimal required packages
 
88
    ivle.jailbuilder.debian.apt_install(build_path,
 
89
            ['python2.5', 'python-cjson', 'python-svn', 'python-configobj'])
 
90
 
 
91
    ivle.jailbuilder.debian.apt_clean(build_path)
 
92
 
 
93
if options.upgrade:
 
94
    # Run apt-get update, apt-get upgrade and apt-get clean.
 
95
    ivle.jailbuilder.debian.mangle_sources_list(build_path, clobber=True)
 
96
    ivle.jailbuilder.debian.mangle_sources_list(build_path, lines=[
 
97
            'deb %s %s%s %s' % (options.apt_mirror, conf['jail']['suite'],
 
98
                                pocket, ' '.join(['main', 'universe']))
 
99
            for pocket in ('', '-updates', '-security')])
 
100
 
67
101
    # Add any extra site apt sources.
68
102
    if conf['jail']['extra_sources']:
69
103
        ivle.jailbuilder.debian.mangle_sources_list(build_path,
75
109
                                            conf['jail']['extra_keys'])
76
110
 
77
111
    ivle.jailbuilder.debian.apt_update_cache(build_path)
78
 
    ivle.jailbuilder.debian.apt_install(build_path,
79
 
                        ['python2.5', 'python-cjson', 'python-svn'])
 
112
    ivle.jailbuilder.debian.apt_upgrade(build_path)
80
113
 
81
114
    # Install any extra site packages.
82
115
    if conf['jail']['extra_packages']:
85
118
 
86
119
    ivle.jailbuilder.debian.apt_clean(build_path)
87
120
 
88
 
if options.upgrade:
89
 
    # Run apt-get update, apt-get upgrade and apt-get clean.
90
 
    ivle.jailbuilder.debian.apt_update_cache(build_path)
91
 
    ivle.jailbuilder.debian.apt_upgrade(build_path)
92
 
    ivle.jailbuilder.debian.apt_clean(build_path)
93
 
 
94
121
if conf['jail']['devmode']:
95
122
    # Copy all console and operating system files into the jail
96
 
    services_path = os.path.join(ivle.conf.share_path, 'services')
 
123
    services_path = os.path.join(conf['paths']['share'], 'services')
97
124
    jail_services_path = os.path.join(build_path, services_path[1:])
98
125
    if os.path.exists(jail_services_path):
99
126
        shutil.rmtree(jail_services_path)
101
128
 
102
129
    # Also copy the IVLE lib directory into the jail
103
130
    # This is necessary for running certain services
104
 
    ivle_site_packages = os.path.join(ivle.conf.python_site_packages, 'ivle')
105
 
    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")
106
145
    if os.path.exists(jail_site_packages):
107
146
        shutil.rmtree(jail_site_packages)
108
147
    shutil.copytree(ivle_site_packages, jail_site_packages)
109
148
 
110
 
    # IMPORTANT: ivle/conf/conf.py contains details which could compromise security
111
 
    # if left in the jail (such as the DB password). We delete it now! It would be
112
 
    # shadowed by the per-user conf.py anyway, but it's best to be safe.
113
 
    os.unlink(os.path.join(jail_site_packages, 'conf/conf.py'))
114
 
    # XXX: Shouldn't copy the compiled files at all, but compile them in the jail!
115
 
    os.unlink(os.path.join(jail_site_packages, 'conf/conf.pyc'))
116
 
 
 
149
    # And finally copy in /etc/hosts, /etc/resolv.conf and /etc/hostname,
 
150
    # so name resolution is less unlikely to work.
 
151
    shutil.copy(
 
152
        '/etc/resolv.conf', os.path.join(build_path, 'etc/resolv.conf'))
 
153
    shutil.copy('/etc/hosts', os.path.join(build_path, 'etc/hosts'))
 
154
    shutil.copy('/etc/hostname', os.path.join(build_path, 'etc/hostname'))
 
155
 
 
156
# Make /tmp and /var/lock un-world-writable. /tmp will be mounted over,
 
157
# and /var/{lock,tmp} should die.
 
158
for path in ('tmp', 'var/lock', 'var/tmp'):
 
159
    path = os.path.join(build_path, path)
 
160
    os.chmod(path, os.stat(path).st_mode & ~stat.S_IWOTH)
 
161
 
 
162
# Verify that nothing in the jail is world-writable.
 
163
# We don't want students to write into places that others can see.
 
164
try:
 
165
    for path, dirs, files in os.walk(build_path):
 
166
        for dname in dirs:
 
167
            d = os.path.join(path, dname)
 
168
            if os.path.islink(d):
 
169
                continue
 
170
            if os.stat(d).st_mode & stat.S_IWOTH:
 
171
                raise UnsafeJail(d)
 
172
 
 
173
        for fname in files:
 
174
            f = os.path.join(path, fname)
 
175
            if os.path.islink(f):
 
176
                continue
 
177
            if os.stat(f).st_mode & stat.S_IWOTH:
 
178
                if (os.path.dirname(f) == os.path.join(build_path, 'dev') and
 
179
                    os.path.basename(f) in ('ptmx', 'null', 'tty', 'full', 'zero',
 
180
                                            'random', 'urandom')
 
181
                    ):
 
182
                    continue
 
183
                raise UnsafeJail(f)
 
184
except UnsafeJail, e:
 
185
    print >> sys.stderr,"""Error: Jail contains world writable path: '%s'.
 
186
This is a security vulnerability as jail template contents are shared between 
 
187
users. Please either make this path world unwriteable or remove it from the 
 
188
jail."""%str(e)
 
189
    sys.exit(1)
 
190
 
 
191
# Copy jail template build to actual jail template
 
192
template_path = conf['paths']['jails']['template']
117
193
if os.spawnvp(os.P_WAIT, 'rsync', ['rsync', '-a', '--delete',
118
 
              build_path + '/', ivle.conf.jail_system]) != 0:
 
194
              build_path + '/', template_path]) != 0:
119
195
    print >> sys.stderr, "Jail copying failed."
120
196
    sys.exit(1)
121
197
 
 
198
# Now mangle things a bit, so we can bind-mount the user bits in.
 
199
# /etc/passwd and /etc/ivle/ivle.conf need to be symlinks to somewhere in /home
 
200
 
 
201
os.rename(os.path.join(template_path, 'etc/passwd'),
 
202
          os.path.join(template_path, 'home/.passwd')
 
203
          )
 
204
os.symlink('../home/.passwd', os.path.join(template_path, 'etc/passwd'))
 
205
 
 
206
os.makedirs(os.path.join(template_path, "etc/ivle"))
 
207
os.symlink('../../home/.ivle.conf',
 
208
           os.path.join(template_path, "etc/ivle/ivle.conf"))