summaryrefslogtreecommitdiff
path: root/kpov_judge
diff options
context:
space:
mode:
authorgasperfele@fri1.uni-lj.si <gasperfele@fri1.uni-lj.si@5cf9fbd1-b2bc-434c-b4b7-e852f4f63414>2015-11-01 22:10:18 +0000
committergasperfele@fri1.uni-lj.si <gasperfele@fri1.uni-lj.si@5cf9fbd1-b2bc-434c-b4b7-e852f4f63414>2015-11-01 22:10:18 +0000
commite355b0f3a097ed73143ad2a7f9a42db3243fa63c (patch)
treec2950ef8cbf78ab65306a75156573c3aee7a6e3a /kpov_judge
parentc861903f376fa38dd7981405cc2980557b325bb5 (diff)
renamed task
git-svn-id: https://svn.lusy.fri.uni-lj.si/kpov-public-svn/kpov-public@348 5cf9fbd1-b2bc-434c-b4b7-e852f4f63414
Diffstat (limited to 'kpov_judge')
-rw-r--r--kpov_judge/tasks/basic_network_gcc/task.py299
-rw-r--r--kpov_judge/tasks/mock_entrance_exam/task.py1
2 files changed, 299 insertions, 1 deletions
diff --git a/kpov_judge/tasks/basic_network_gcc/task.py b/kpov_judge/tasks/basic_network_gcc/task.py
new file mode 100644
index 0000000..6aa2144
--- /dev/null
+++ b/kpov_judge/tasks/basic_network_gcc/task.py
@@ -0,0 +1,299 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# TODO:
+# - check if everything is filled in (computers, params, preparation)
+# - improve scoring
+# - test
+# - switch to a real SSH/SFTP client to properly handle filenames
+
+instructions = {
+ 'si': u'''
+Postavite dva navidezna računalnika - SimpleArbiter in Student.
+Oba naj bosta povezana na internet. Poleg tega mora biti
+Student na naslovu {student_IP} dostopen s SimpleArbiter.
+
+Računajte, da se na Student ob zagonu zažene program {net_prog_name},
+ki vam spreminja nastavitve mrežne kartice.
+
+V domačem imeniku uporabnika student obstaja program {P_c} v programskem jeziku C.
+Prevedite ga v program z imenom {P_executable}.
+Izvorna koda je namenoma pokvarjena tako, da so vanjo vrinjeni nepotrebni znaki.
+Pred prevajanjem jo morate popraviti.
+
+Napišite skripto ali program {P_script} v domačem imeniku uporabnika student, ki:
+- požene {P_executable} z argumentom "{arg_c}" in mu na standardni vhod pripelje vrednost spremenljivke {env_c}
+- vse, kar {P_executable} izpiše na stderr, spravi v datoteko {out_stderr_c}.
+- vse vrstice, ki jih {P_executable} izpiše na stdout in vsebujejo zaporedje znakov "ma", zapiše v {out_stdout_c}.
+
+
+Lastnik vseh ustvarjenih datotek mora biti uporabnik student.
+Gesla uporabnika student (vaje) ne smete spreminjati.''',
+ 'en': u'''
+''',
+}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ {
+ 'name': 'simpleArbiter',
+ },
+ ],
+ 'network_interfaces': [
+ {'network': 'net1'},
+ {'network': 'net2'},
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': True,
+ },
+ 'Student': {
+ 'disks': [
+ {'name': 'student-entrance'}
+ ],
+ 'flavor': 'm1.tiny',
+ 'network_interfaces': [{'network': 'net1'}],
+ 'config_drive': True,
+ }
+}
+
+networks = {
+ 'net1': {
+ 'public': True,
+ },
+ 'net2': {
+ 'public': False,
+ },
+}
+
+params_meta = {
+ 'student_IP': {
+ 'descriptions': { 'si': 'IP naslov SimpleStudent', 'en': 'IP address of SimpleStudent',
+ }, 'w': False, 'public': True, 'type': 'IP', 'generated': True,
+ },
+ 'net_prog_name': {
+ 'descriptions': { 'si': 'Ime programa, ki ponastalvlja naslov', 'en': 'The name of the program resetting the network'
+ }, 'w': False, 'public': True, 'type': 'filename', 'generated': True,
+ },
+ 'P_c': {
+ 'descriptions': { 'si': 'Datoteka s programom v C', 'en': 'Filename of the program in C',
+ }, 'w': False, 'public': True, 'type': 'filename', 'generated': True,
+ },
+ 'P_executable': { 'descriptions': { 'si': 'Ime prevedenega programa v C', 'en': 'Filename of the compiled C program'
+ }, 'w': False, 'public': True, 'type': 'filename', 'generated': True,
+ },
+ 'arg_c': {
+ 'descriptions': { 'si': 'Vrednost argumenta', 'en': 'Argument value',
+ }, 'w': False, 'public': True, 'type': 'short_text', 'generated': True,
+ },
+ 'env_c': {
+ 'descriptions': { 'si': 'Ime okoljske spremenljivke', 'en': 'The name of the environment environment',
+ }, 'w': False, 'public': True, 'type': 'short_text', 'generated': True,
+ },
+ 'out_stderr_c': {
+ 'descriptions': { 'si': 'Datoteka z napakami', 'en': 'File to store errors',
+ }, 'w': False, 'public': True, 'type': 'filename', 'generated': True,
+ },
+ 'P_script': {
+ 'descriptions': { 'si': 'Ime skripte', 'en': 'Filename of the script',
+ }, 'w': False, 'public': True, 'type': 'filename', 'generated': True,
+ },
+ 'out_stdout_c': {
+ 'descriptions': { 'si': 'Datoteka z izhodom', 'en': 'File to store the output',
+ }, 'w': False, 'public': True, 'type': 'filename', 'generated': True,
+ },
+ 'param_gen_seed': {
+ 'descriptions': { 'si': 'Nakljucno seme', 'en': 'Random seed',
+ }, 'w': False, 'public': True, 'type': None, 'generated': True,
+ },
+ 'c_destroy_gen_seed': {
+ 'descriptions': { 'si': 'Nakljucno seme za kvarjenje kode v C', 'en': 'Random seed for destroying the C code',
+ }, 'w': False, 'public': False, 'type': None, 'generated': True,
+ }
+
+}
+
+def task(student_IP, net_prog_name,
+ P_c, P_executable, arg_c, env_c, out_stderr_c, out_stdout_c, P_script,
+ param_gen_seed):
+ import pxssh
+ import random
+ conn = pxssh.pxssh()
+ conn.login(student_IP, 'student', 'vaje')
+ results = dict()
+ r = random.Random(int(param_gen_seed))
+ env_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in xrange(11)])
+
+ arg_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in xrange(13)])
+ stdin_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in xrange(17)])
+ conn.sendline('ls -l {}'.format(P_script))
+ conn.prompt()
+ results['script_ls'] = conn.before
+ conn.sendline('ls -l {}'.format(P_executable))
+ conn.prompt()
+ results['executable_ls'] = conn.before
+ conn.sendline('export {}={}; {}'.format(env_c, env_val, P_script))
+ conn.prompt()
+ results['script_run'] = conn.before
+ conn.sendline('cat {}'.format(out_stderr_c))
+ conn.prompt()
+ results['script_stderr'] = conn.before
+ conn.sendline('cat {}'.format(out_stdout_c))
+ conn.prompt()
+ results['script_stdout'] = conn.before
+ conn.sendline('echo "{}" | {} "{}" 2> /dev/null'.format(stdin_val, P_executable, arg_val))
+ conn.prompt()
+ results['prog_stdout'] = conn.before
+ conn.sendline('echo "{}" | {} "{}" > /dev/null'.format(stdin_val, P_executable, arg_val))
+ conn.prompt()
+ results['prog_stderr'] = conn.before
+ conn.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ import random
+ r = random.Random(user_id+'evil cornholio')
+ params = kpov_random_helpers.default_gen(user_id, params_meta)
+ homedir = '/home/student/'
+ params['env_c'] = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ') for i in xrange(5)])
+ params['P_c'] = "".join([r.choice('abcdefghijklmnoprst') for i in xrange(5)]) + ".c"
+ params['param_gen_seed'] = str(r.randint(0, 2**24))
+ params['c_destroy_gen_seed'] = str(r.randint(0, 2**24))
+ dest_net = kpov_random_helpers.IPv4_subnet_gen(r, '10.0.2.128/26', 26)
+ params['student_IP'] = kpov_random_helpers.IPv4_addr_gen(r, dest_net)[0]
+ for k in ['P_c', 'P_executable', 'out_stderr_c', 'P_script', 'out_stdout_c']:
+ params[k] = homedir + params[k]
+ return params
+
+def task_check(results, params):
+ import os
+ def test_out_gen(arg, var):
+ s_out = ""
+ s_err = ""
+ r = 0
+ arg_len = len(arg)
+ env_len = len(var)
+ for i in xrange(100):
+ s_out += chr(32 + ((ord(arg[i % arg_len]) ^ ord(var[i % env_len])) % 64))
+ r += ord(arg[i % arg_len]) + ord(var[i % env_len]) + i;
+ if (i % 20 == 0):
+ s_out += "RAUS\r\n";
+ if (i % 31 == 0):
+ s_out += 'ma'
+ s_err += chr((r % 32) + ord('A'));
+ if (i % 23 == 0):
+ s_err += "PATACIS\r\n"
+ retval = r % 16
+ s_err += '\r\n'
+ s_out += '\r\n'
+ return(s_out, s_err, retval)
+ score = 0
+ hints = []
+ r = random.Random(int(params['param_gen_seed']))
+ env_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in xrange(11)])
+ arg_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in xrange(13)])
+ stdin_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in xrange(17)])
+ expected_script_stdout, expected_script_stderr, rval = test_out_gen(
+ params['arg_c'], env_val
+ )
+ expected_script_stderr = 'cat {}\r\n'.format(params['out_stderr_c']) + expected_script_stderr
+ # hints += [expected_script_stderr, results['script_run'], results['script_stderr'], params['arg_c'], env_val]
+ if expected_script_stderr != results['script_stderr']:
+ hints += ['wrong script stderr']
+ else:
+ score += 2
+ split_stdout = expected_script_stdout.split('\r\n')
+ expected_script_stdout = "\r\n".join([ i for i in split_stdout if i.find('ma') >= 0])
+ expected_script_stdout = 'cat {}\r\n'.format(params['out_stdout_c']) + expected_script_stdout + "\r\n"
+ if expected_script_stdout != results['script_stdout']:
+ hints += ['wrong script stdout']
+ else:
+ score += 2
+ expected_prog_stdout, expected_prog_stderr, rval = test_out_gen(
+ arg_val, stdin_val
+ )
+ if expected_prog_stderr != results['prog_stderr'][-len(expected_prog_stderr):]:
+ hints += ['wrong program stderr']
+ else:
+ score += 2
+ if expected_prog_stdout != results['prog_stdout'][-len(expected_prog_stdout):]:
+ hints += ['wrong program stdout']
+ else:
+ score += 2
+ if results['script_ls'].find('-r') < 0:
+ hints += ['script not found']
+ else:
+ score += 1
+ if results['executable_ls'].find('xr') < 0:
+ hints += ['C executable not found']
+ else:
+ score += 1
+ return score, hints
+
+def prepare_disks(templates, params):
+ c_source = '''#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+/* Odstranite vse odvecne velike crke Q, W ali X in program se bo prevedel. */
+
+int main(int argc, char **argv){
+ unsigned char *arg;
+ unsigned char var[255];
+ int i, arg_len, env_len, r;
+ scanf("%s", var);
+ arg = argv[1];
+ arg_len = strlen(argv[1]);
+ env_len = strlen(var);
+ r = 0;
+ for (i = 0; i<100; i++){
+ printf("%c", 32 + (arg[i % arg_len] ^ var[i % env_len]) % 64);
+ r += (int)arg[i % arg_len] + (int)var[i % env_len] + i;
+ if (i % 17 == 0){
+ printf("RAUS\\n");
+ }
+ if (i % 29 == 0){
+ printf("ma");
+ }
+ fprintf(stderr, "%c", (r % 31) + 'A');
+ if (i % 23 == 0){
+ fprintf(stderr, "PATACIS\\n");
+ }
+ }
+ printf("\\n");
+ fprintf(stderr, "\\n");
+ return r % 16;
+}
+'''
+ evil_shell_source = """#!/bin/bash -e
+{ while true; do
+ ifconfig eth1 10.0.4.19 2> /dev/null;
+ ifconfig eth0 10.0.4.20 2> /dev/null;
+ ifconfig eth2 10.0.4.21 2> /dev/null;
+ sleep 10;
+done; }&
+"""
+ import random
+ d = templates['student-entrance']
+ r = random.Random(params['c_destroy_gen_seed'])
+ destroyed_c_source = c_source[:110]
+ for c in c_source[110:]:
+ i = r.randint(0, 5)
+ if i == 1:
+ destroyed_c_source += 'QW'
+ if i == 2:
+ destroyed_c_source += 'XW'
+ if i == 3:
+ destroyed_c_source += 'QX'
+ destroyed_c_source += c
+ d.write(params['P_c'], destroyed_c_source)
+ d.chown(1000, 1000, params['P_c'])
+ sh_path = r.choice(['/usr/share/doc', '/var/lib', '/usr/local/share', '/etc/alternatives'])
+ sh_file = sh_path + '/' + params['net_prog_name']
+ d.write(sh_file, evil_shell_source)
+ d.chmod(0775, sh_file)
+ d.write("/etc/rc.local", """#!/bin/sh -e
+export PATH=$PATH:{}
+{} &
+
+exit 0
+""".format(sh_path, params['net_prog_name']))
diff --git a/kpov_judge/tasks/mock_entrance_exam/task.py b/kpov_judge/tasks/mock_entrance_exam/task.py
index 6aa2144..96965be 100644
--- a/kpov_judge/tasks/mock_entrance_exam/task.py
+++ b/kpov_judge/tasks/mock_entrance_exam/task.py
@@ -26,7 +26,6 @@ Napišite skripto ali program {P_script} v domačem imeniku uporabnika student,
- vse, kar {P_executable} izpiše na stderr, spravi v datoteko {out_stderr_c}.
- vse vrstice, ki jih {P_executable} izpiše na stdout in vsebujejo zaporedje znakov "ma", zapiše v {out_stdout_c}.
-
Lastnik vseh ustvarjenih datotek mora biti uporabnik student.
Gesla uporabnika student (vaje) ne smete spreminjati.''',
'en': u'''