def main(args): # pragma: no cover """ Prints a json list: [ ("Test description", "value") ] TODO: what about multi-file submission? """ import logging from pprint import pprint from codejail.jail_code import configure import getpass logging.basicConfig(level=logging.DEBUG) if len(args) != 2: return configure("python", sys.executable, user=getpass.getuser()) (grader_path, submission_path) = args with open(submission_path) as f: submission = f.read().decode('utf-8') grader_config = {"lang": "eo"} grader_path = path(grader_path).abspath() g = JailedGrader(grader_root=grader_path.dirname().parent.parent) pprint(g.grade(grader_path, grader_config, submission))
def enable_codejail(self, codejail_config): """ Enable codejail for the process. codejail_config is a dict like this: { "name": "python", "bin_path": "/path/to/python", "user": "******", "limits": { "CPU": 1, ... } } limits are optional user defaults to the current user """ name = codejail_config["name"] bin_path = codejail_config['bin_path'] user = codejail_config.get('user', getpass.getuser()) jail_code.configure(name, bin_path, user=user) limits = codejail_config.get("limits", {}) for name, value in limits.items(): jail_code.set_limit(name, value) self.log.info("configured codejail -> %s %s %s", name, bin_path, user) return name
def configure_by_language(config_dict, prefix, limits, user=None, env=None): for lang, options in config_dict.items(): binary = options['bin'] if not shutil.which(binary): msg = "can't find {} binary for {}!" logger.warning(msg.format(binary, lang)) else: lang_limits = dict(limits) if 'limits' in options: lang_limits.update(options['limits']) lang_env = env if 'env' in options: lang_env = env.copy() if env is not None else {} lang_env.update(options['env']) jail_code.configure(prefix + lang, binary, lang_limits, user=user, extra_args=options['args'], env=lang_env)
def setUp(self): configure("python", sys.executable, user=getpass.getuser()) self.grader_root = path(__file__).dirname() / 'fixtures' self.g = JailedGrader(grader_root=self.grader_root)
def configure_jail_code(settings): # we need HOME because we don't want jailed code to read /etc/passwd if not settings.SANDBOX_USER: home = os.path.expanduser('~') else: home = pwd.getpwnam(settings.SANDBOX_USER).pw_dir python_env = settings.SANDBOX_ENV.copy() python_env.update({"HOME": home}) jail_code.configure('python', settings.SANDBOX_PYTHON, settings.SANDBOX_LIMITS, user=settings.SANDBOX_USER, env=python_env) jail_code.configure('user_code', './main', settings.USER_CODE_LIMITS, user=settings.SANDBOX_USER, env=settings.SANDBOX_ENV) if settings.SANDBOX_JAVA: java_limits, args = get_limits_for_java(settings.USER_CODE_LIMITS) jail_code.configure('run_java', settings.SANDBOX_JAVA, java_limits, extra_args=args, user=settings.SANDBOX_USER, env=settings.SANDBOX_ENV) if settings.SANDBOX_JAVA8: java_limits, args = get_limits_for_java(settings.USER_CODE_LIMITS) jail_code.configure('run_java8', settings.SANDBOX_JAVA8, java_limits, extra_args=args, user=settings.SANDBOX_USER, env=settings.SANDBOX_ENV) compilers_env = settings.SANDBOX_ENV.copy() compilers_env.update({"PATH": os.environ["PATH"], "HOME": home}) configure_by_language(settings.COMPILERS, 'compile_', settings.COMPILER_LIMITS, env=compilers_env) if 'java' in settings.COMPILERS: options = settings.COMPILERS['java'] java_limits, args = get_limits_for_java(settings.COMPILER_LIMITS) args = ['-J' + arg for arg in args] jail_code.configure('compile_java', options['bin'], java_limits, extra_args=options['args'] + args, env=compilers_env) if 'java8' in settings.COMPILERS: options = settings.COMPILERS['java8'] jail_code.configure('compile_java8', options['bin'], java_limits, extra_args=options['args'] + args, env=compilers_env) if 'scala' in settings.COMPILERS: options = settings.COMPILERS['scala'] jail_code.configure('compile_scala', options['bin'], java_limits, extra_args=options['args'] + args, env=dict(compilers_env, JAVA_HOME=settings.SANDBOX_JAVA_HOME)) java_limits, args = get_limits_for_java(settings.USER_CODE_LIMITS) jail_code.configure('run_scala', options['bin'][:-1], # scalac -> scala java_limits, user=settings.SANDBOX_USER, env=dict(settings.SANDBOX_ENV, JAVA_HOME=settings.SANDBOX_JAVA_HOME)) configure_by_language(settings.INTERPRETERS, 'run_', settings.USER_CODE_LIMITS, user=settings.SANDBOX_USER, env=settings.SANDBOX_ENV) run_python3_env = settings.SANDBOX_ENV.copy() run_python3_env.update({"HOME": home}) jail_code.configure('run_python3', settings.SANDBOX_PYTHON, settings.USER_CODE_LIMITS, user=settings.SANDBOX_USER, env=run_python3_env)
# evaldontevil # (eval, don't evil) # part of the Pythontutor project # https://github.com/vpavlenko/pythontutor-ru from json import dumps, loads from os.path import dirname from sys import stderr from codejail.jail_code import configure, jail_code, set_limit from evaldontevil.config import * configure('python', VENV_PYTHON + '/bin/python', user=USER) set_limit('CPU', CPUTIME_LIMIT) set_limit('REALTIME', REALTIME_LIMIT) set_limit('MEM', MEM_LIMIT) set_limit('FSIZE', FSIZE_LIMIT) class ExecuteResult: def __init__(self, jailres): self.result = 'ok' self.stdout = '' self.stderr = '' if jailres.status & 128 != 0: self.result = 'realtime_limited' return
source_code = '' with open(sys.argv[7], "r") as f: source_code = f.read() print "Source code len: %d" % len(source_code) stdin_contents = '' with open(sys.argv[6], "r") as f: stdin_contents = f.read() output_file = sys.argv[8] print "Output file: %s" % output_file unit_test_code = None if len(sys.argv) >= 10: with open(sys.argv[9], "r") as f: unit_test_code = f.read() print "Unit test code len: %d" % len(unit_test_code) jail_code.configure('python', python_path, sandbox_user) jail_code.set_limit('CPU', max_cpu) jail_code.set_limit('VMEM', max_memory) jail_code.set_limit('REALTIME', max_real_time) result = jail_code.jail_code('python', source_code, \ None, None, stdin_contents, "codemarathon", unit_test_code) cpu_time = result.res_data.ru_utime + result.res_data.ru_stime memory_usage = result.res_data.ru_maxrss * resource.getpagesize() / 1024 status = result.status error_message = result.stderr with open(output_file, "w") as f: f.write(result.stdout) with open("stat", "w") as f:
def setUpClass(cls): configure('python3', settings.PYTHON_SANDBOX_PATH)
# evaldontevil # (eval, don't evil) # part of the Pythontutor project # https://github.com/vpavlenko/pythontutor-ru from json import dumps, loads from os.path import dirname from sys import stderr from codejail.jail_code import configure, jail_code, set_limit from evaldontevil.config import * configure('python', VENV_PYTHON + '/bin/python', user=USER) set_limit('CPU', CPUTIME_LIMIT) set_limit('REALTIME', REALTIME_LIMIT) set_limit('MEM', MEM_LIMIT) set_limit('FSIZE', FSIZE_LIMIT) class ExecuteResult: def __init__(self, jailres): self.result = 'ok' self.stdout = '' self.stderr = '' if jailres.status & 128 != 0: self.result = 'realtime_limited'
from zipfile import ZipFile from django import forms from django.conf import settings from codejail.jail_code import jail_code, configure from django.core.exceptions import ValidationError from django.core.files.temp import NamedTemporaryFile from django.core.files.uploadedfile import InMemoryUploadedFile from common.forms import ModelForm from tasks.models import TestCase configure('python3', settings.PYTHON_SANDBOX_PATH) class DeleteIOFileForm(ModelForm): name = 'Delete Test Case' urlname = 'deleteiofile' valid_users = (1,) case = forms.IntegerField(label='case') class Meta: model = TestCase fields = ('case',) def clean_case(self, case): case = TestCase.objects.filter(id=int(case)).first() if case is None: raise ValidationError('No test case matching the id') if case.task.course.teacher != self.user: raise ValidationError('Not enough permissions')