#!/usr/bin/env python # -*- coding: utf-8 -*- # kpov_util should be imported by add_assignment.py # TODO: finish this! instructions = { 'si':""" Postavite dva navidezna racunalnika: - SimpleArbiterDhcpRdate s slike diska simpleArbiterRdate ter - rdateClient. Na rdateClient ustvarite uporabnika test z geslom test. Nastavite cas na rdateClient tako, da kot rdate strežnik uporabite SimpleArbiterDhcpRdate. Nato v domacem imeniku uporabnika test ustvarite program z imenom {PROGRAM_FILENAME}. Program naj prebere 4 byte podatkov s standardnega vhoda in jih pretvori v predznaceno celo število, pri čemer naj uporablja zapis z debelim koncem (big endian). Število naj program izpiše na standardni izhod v obliki niza. """, 'en':""" Setup two virtual machines: - SimpleArbiterDhcpRdate from disk image simpleArbiterRdate and - rdateClient. On rdateClient, create a user with the username test and password test. Set the time on rdateClient using rdate with SimpleArbiterDhcpRdate as the server. Then, write a program called {PROGRAM_FILENAME} and put it in user test's home directory. The program should read 4 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', }, #{ 'name': 'CDROM', # 'options':{'readonly': True}, # 'parts': [],# no parts, no mounting. #} ], 'network_interfaces': [{'network': 'net1'}], 'flavor': 'm1.tiny', 'config_drive': False }, 'SimpleArbiter': { 'disks': [ { 'name': 'simpleArbiterDhcpGWRdate', # attempt automount }, #{ 'name': 'CDROM', # 'options': {'readonly': True}, # 'parts': [{'dev': 'b1', 'path': '/cdrom'}], #}, ], '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 pexpect import paramiko from paramiko import SSHClient import random import struct import base64 results = dict() peer_user = 'test' peer_passwd = 'test' client = SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(IP_RDATECLIENT, username=peer_user, password=peer_passwd) #client.login(IP_RDATECLIENT, peer_user, peer_passwd) r = random.Random(PROGRAM_FILENAME) for i in range(10): stdin, stdout, stderr = client.exec_command( '~/{}'.format(PROGRAM_FILENAME)) data = struct.pack("!I", r.randint(0, 2**32)) stdin.write(data) results['in_' + str(i)] = base64.encodestring(data) results['out_' + str(i)] = stdout.read() stdin, stdout, stderr = client.exec_command( 'date -u +"%s"') #client.sendline('date -u "%s"') #client.prompt() results['date'] = stdout.read() results['ldate'] = pexpect.run('date -u +"%s"') client.close() 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 # print results 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"] # print str(struct.unpack("!I", data)[0]), res.strip() 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['simpleArbiterDhcp'] # print templates # print 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() + 2208988800 + offset 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)