# 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': '''\
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:
{{P_executable}}
z argumentom "{{arg_c}}"
in mu na standardni vhod pripelje vrednost spremenljivke {{env_c}}
;
{{P_executable}}
izpiše na stderr, spravi v datoteko {{out_stderr_c}}
; in
{{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': '''\
Set up two virtual machines - SimpleArbiter and Student. Both should be connected to the internet. Student should also be accessible from SimpleArbiter at the address {{student_IP}}
.
Keep in mind that a program called {{net_prog_name}}
starts on Student on each boot. This program may change your network settings.
There is a program called {{P_c}}
in student
’s home directory. Compile it into a program called {{P_executable}}
. The source code is intentionally broken so that unneccessarry characters are inserted into the file. You have to fix the file before compiling.
Also, write a script or program called {{P_script}}
in student
’s home directory. The script should:
{{P_executable}}
with the argument {{arg_c}}
and pipe the value of the environment variable {{env_c}}
into {{P_executable}}
’s standard input;
{{P_executable}}
into a file called {{out_stderr_c}}
; and
{{P_executable}}
outputs and which contains the character sequence ma
into {{out_stdout_c}}
.
The owner of all created files should be student
. You are not allowed to change student
’s password (vaje
).
''',
}
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'}, {'network': 'net3'}],
'config_drive': True,
}
}
networks = {
'net1': {
'public': False,
},
'net2': {
'public': True,
},
'net3': {
'public': True,
}
}
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 random
r = random.Random(int(param_gen_seed))
env_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in range(11)])
arg_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in range(13)])
stdin_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in range(17)])
return kpov_util.ssh_test(student_IP, 'student', 'vaje', (
('script_ls', 'ls -l {}'.format(P_script)),
('executable_ls', 'ls -l {}'.format(P_executable)),
('script_run', 'export {}={}; {}'.format(env_c, env_val, P_script)),
('script_stderr', 'cat {}'.format(out_stderr_c)),
('script_stdout', 'cat {}'.format(out_stdout_c)),
('prog_stdout', 'echo "{}" | {} "{}" 2> /dev/null'.format(stdin_val, P_executable, arg_val)),
('prog_stderr', 'echo "{}" | {} "{}" > /dev/null'.format(stdin_val, P_executable, arg_val)),
))
def gen_params(user_id, params_meta):
import random
r = random.Random(user_id+'evil cornholio')
params = kpov_util.default_gen(user_id, params_meta)
homedir = '/home/student/'
params['env_c'] = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ') for i in range(5)])
params['P_c'] = "".join([r.choice('abcdefghijklmnoprst') for i in range(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_util.IPv4_subnet_gen(r, '10.0.2.128/26', 26)
params['student_IP'] = kpov_util.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 range(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 % 17 == 0):
s_out += "RAUS\r\n";
if (i % 29 == 0):
s_out += 'ma'
s_err += chr((r % 31) + 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 = []
if results['ssh'] is not True:
hints += ['ssh failed: ' + results['ssh']]
r = random.Random(int(params['param_gen_seed']))
env_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in range(11)])
arg_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in range(13)])
stdin_val = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ012345') for i in range(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, task_params, global_params):
c_source = '''#include