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

« back to all changes in this revision

Viewing changes to ivle/interpret.py

  • Committer: William Grant
  • Date: 2009-02-23 23:47:02 UTC
  • mfrom: (1099.1.211 new-dispatch)
  • Revision ID: grantw@unimelb.edu.au-20090223234702-db4b1llly46ignwo
Merge from lp:~ivle-dev/ivle/new-dispatch.

Pretty much everything changes. Reread the setup docs. Backup your databases.
Every file is now in a different installed location, the configuration system
is rewritten, the dispatch system is rewritten, URLs are different, the
database is different, worksheets and exercises are no longer on the
filesystem, we use a templating engine, jail service protocols are rewritten,
we don't repeat ourselves, we have authorization rewritten, phpBB is gone,
and probably lots of other things that I cannot remember.

This is certainly the biggest commit I have ever made, and hopefully
the largest I ever will.

Show diffs side-by-side

added added

removed removed

Lines of Context:
134
134
        del os.environ[k]
135
135
    for (k,v) in req.get_cgi_environ().items():
136
136
        os.environ[k] = v
137
 
    fixup_environ(req)
 
137
    fixup_environ(req, script_path)
138
138
 
139
139
    # usage: tramp uid jail_dir working_dir script_path
140
140
    pid = subprocess.Popen(
141
 
        [trampoline, str(uid), jail_dir, working_dir, interpreter,
 
141
        [trampoline, str(uid), ivle.conf.jail_base, ivle.conf.jail_src_base,
 
142
         ivle.conf.jail_system, jail_dir, working_dir, interpreter,
142
143
        script_path],
143
144
        stdin=f, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
144
145
        cwd=tramp_dir)
358
359
    # python-server-page
359
360
}
360
361
 
361
 
def fixup_environ(req):
 
362
def fixup_environ(req, script_path):
362
363
    """Assuming os.environ has been written with the CGI variables from
363
364
    apache, make a few changes for security and correctness.
364
365
 
384
385
        del env['PATH']
385
386
    except: pass
386
387
 
387
 
    # Remove SCRIPT_FILENAME. Not part of CGI spec (see SCRIPT_NAME).
388
 
 
389
 
    # PATH_INFO is wrong because the script doesn't physically exist.
390
 
    # Apache makes it relative to the "serve" app. It should actually be made
391
 
    # relative to the student's script. intepretservice does that in the jail,
392
 
    # so here we just clear it.
393
 
    env['PATH_INFO'] = ''
394
 
    env['PATH_TRANSLATED'] = ''
395
 
 
396
388
    # CGI specifies that REMOTE_HOST SHOULD be set, and MAY just be set to
397
389
    # REMOTE_ADDR. Since Apache does not appear to set this, set it to
398
390
    # REMOTE_ADDR.
399
391
    if 'REMOTE_HOST' not in env and 'REMOTE_ADDR' in env:
400
392
        env['REMOTE_HOST'] = env['REMOTE_ADDR']
401
393
 
 
394
    env['PATH_INFO'] = ''
 
395
    del env['PATH_TRANSLATED']
 
396
 
 
397
    normuri = os.path.normpath(req.uri)
 
398
    env['SCRIPT_NAME'] = normuri
 
399
 
402
400
    # SCRIPT_NAME is the path to the script WITHOUT PATH_INFO.
403
 
    script_name = req.uri
404
 
    env['SCRIPT_NAME'] = script_name
 
401
    # We don't care about these if the script is null (ie. noop).
 
402
    # XXX: We check for /home because we don't want to interfere with
 
403
    # CGIRequest, which fileservice still uses.
 
404
    if script_path and script_path.startswith('/home'):
 
405
        normscript = os.path.normpath(script_path)
 
406
 
 
407
        uri_into_jail = studpath.url_to_jailpaths(os.path.normpath(req.path))[2]
 
408
 
 
409
        # PATH_INFO is wrong because the script doesn't physically exist.
 
410
        env['PATH_INFO'] = uri_into_jail[len(normscript):]
 
411
        if len(env['PATH_INFO']) > 0:
 
412
            env['SCRIPT_NAME'] = normuri[:-len(env['PATH_INFO'])]
405
413
 
406
414
    # SERVER_SOFTWARE is actually not Apache but IVLE, since we are
407
415
    # custom-making the CGI request.
410
418
    # Additional environment variables
411
419
    username = studpath.url_to_jailpaths(req.path)[0]
412
420
    env['HOME'] = os.path.join('/home', username)
 
421
 
 
422
class ExecutionError(Exception):
 
423
    pass
 
424
 
 
425
def execute_raw(user, jail_dir, working_dir, binary, args):
 
426
    '''Execute a binary in a user's jail, returning the raw output.
 
427
 
 
428
    The binary is executed in the given working directory with the given
 
429
    args. A tuple of (stdout, stderr) is returned.
 
430
    '''
 
431
 
 
432
    tramp = location_cgi_python
 
433
    tramp_dir = os.path.split(location_cgi_python)[0]
 
434
 
 
435
    # Fire up trampoline. Vroom, vroom.
 
436
    proc = subprocess.Popen(
 
437
        [tramp, str(user.unixid), ivle.conf.jail_base,
 
438
         ivle.conf.jail_src_base, ivle.conf.jail_system, jail_dir,
 
439
         working_dir, binary] + args,
 
440
        stdin=subprocess.PIPE, stdout=subprocess.PIPE,
 
441
        stderr=subprocess.PIPE, cwd=tramp_dir, close_fds=True)
 
442
    exitcode = proc.wait()
 
443
 
 
444
    if exitcode != 0:
 
445
        raise ExecutionError('subprocess ended with code %d, stderr %s' %
 
446
                             (exitcode, proc.stderr.read()))
 
447
    return (proc.stdout.read(), proc.stderr.read())