diff options
Diffstat (limited to 'kpov_judge/tasks')
-rw-r--r-- | kpov_judge/tasks/basic_network_gcc/task.py | 299 | ||||
-rw-r--r-- | kpov_judge/tasks/mock_entrance_exam/task.py | 1 |
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''' |