# SPDX-License-Identifier: AGPL-3.0-or-later # kpov_util should be imported by add_assignment.py # TODO: finish this! instructions = { 'si': '''\
Postavite dva navidezna računalnika: SimpleArbiterDhcpRdate in rdateClient.
Nastavite čas na rdateClient tako, da kot rdate strežnik uporabite SimpleArbiterDhcpRdate.
Na rdateClient ustvarite uporabnika test
z geslom test
. V domačem imeniku uporabnika test
ustvarite program z imenom {{PROGRAM_FILENAME}}
. Program naj prebere štiri bajte podatkov s standardnega vhoda in jih pretvori v predznačeno celo število, pri čemer naj uporablja zapis z debelim koncem (angl. big endian). Število naj program izpiše na standardni izhod v obliki niza.
''',
'en': '''\
Set up two virtual machines: SimpleArbiterDhcpRdate and rdateClient.
Set the time on rdateClient using rdate with SimpleArbiterDhcpRdate as the server.
On rdateClient create a user with the username test
and password test
. Then, write a program called {{PROGRAM_FILENAME}}
and put it in user test
’s home directory. The program should read four bytes of data from standard input, convert them into a signed integer using big endian byte ordering and output the resulting integer (as a string) to standard output.
''',
}
computers = {
'rdateClient': {
'disks': [
{ 'name': 'student-rdate',
},
],
'network_interfaces': [{'network': 'net1'}],
'flavor': 'm1.tiny',
'config_drive': False
},
'SimpleArbiter': {
'disks': [
{ 'name': 'simpleArbiterDhcpGWRdate',
},
],
'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
'flavor': 'm1.tiny',
'config_drive': False
}
}
networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
# Tu sem dolocil parametre
params_meta = {
'RDATE_OFFSET':{'descriptions': {'si': 'Napaka v času pri rdate', 'en': 'Timekeeping error for rdate'}, 'w': False, 'public': False, 'type': 'integer', 'generated': True},
'PROGRAM_FILENAME':{'descriptions': {'si': 'Ime programa', 'en': 'program filename'}, 'w': False, 'public': True, 'type': 'integer', 'generated': True},
'IP_RDATECLIENT':{'descriptions': {'si': 'IP rdateClient', "en": "rdateClient's IP"}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
}
def task(IP_RDATECLIENT, PROGRAM_FILENAME):
import collections
import base64
import random
import struct
import pexpect
r = random.Random(PROGRAM_FILENAME)
results = collections.defaultdict(str)
tests = []
for i in range(10):
data = struct.pack("!I", r.randint(0, 2**32))
results['in_'+str(i)] = data_ascii = base64.encodestring(data)
tests += [('out_'+str(i), 'echo "{}" | base64 -d | ~/{}'.format(data_ascii.decode().strip(), PROGRAM_FILENAME))]
tests += [('date', 'date -u +"%s"')]
results.update(
kpov_util.ssh_test(IP_RDATECLIENT, 'test', 'test', tests))
results['ldate'] = pexpect.run('date -u +"%s"')
return results
#Dolocil sem tri parametre in sicer jih lahko vidite v prams_meta,
#zato prosim da jih upostevate v naslednih nalogah.
def gen_params(user_id, params_meta):
import socket
import struct
import datetime
params = dict()
r = random.Random(user_id)
params['PROGRAM_FILENAME'] = kpov_util.fname_gen(r, False)
params['RDATE_OFFSET'] = str(r.randint(-2**24, 2**24))
return params
def task_check(results, params):
import random
import struct
import base64
r = random.Random(params['PROGRAM_FILENAME'])
score = 0.0
hints = []
for i in range(10):
data = base64.decodestring(results['in_' + str(i)])
x = struct.pack("!I", r.randint(0, 2**32))
if data != x:
hints += ["data: " + str((data,)) + " != " + str((x,))]
break
res = results['out_' + str(i)]
if str(struct.unpack("!i", data)[0]) == res.strip():
score += 0.5
else:
hints += ["wrong convert"]
if abs(int(results['ldate']) + \
int(params['RDATE_OFFSET']) - int(results['date'])) < 3:
score += 5
else:
hints += ["wrong offset"]
return score, hints
def prepare_disks(templates, task_params, global_params):
d = templates['simpleArbiterDhcpGWRdate']
s1 = """service "time_tcp" {{
enabled yes;
protocol tcp;
port "time";
user "nobody";
exec "/usr/local/bin/kpovrdate {RDATE_OFFSET}";
server "/usr/sbin/tcpd";
wait no;
}}
""".format(**task_params)
d.write('/etc/rlinetd.d/time', s1)
s2 = """#!/usr/bin/python
import struct
import time
import sys
offset = int(sys.argv[1])
t = time.time() + offset # used to have + 2208988800
sys.stdout.write(struct.pack("!I", int(t)))
"""
d.write('/usr/local/bin/kpovrdate', s2)
d.chmod(0o775, '/usr/local/bin/kpovrdate')
write_default_config(templates['simpleArbiterDhcpGWRdate'], global_params)