# 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)