#!/usr/bin/env python # -*- coding: utf-8 -*- # kpov_random_helpers should be imported by add_assignment.py instructions = { 'si':u""" Ustvari dva navidezna računalnika - SimpleArbiter z diska simpleArbiterDhcp ter RadiusServer. Na RadiusServer namesti FreeRadius ter MySQL. Ustvari mysql podatkovno bazo z imenom {MYSQL_DB_NAME}. Ustvari mysql uporabnika z imenom {MYSQL_ADMIN_USER} in geslom {MYSQL_ADMIN_PASSWORD}, ki naj ima poln dostop do te baze. Prijava za tega uporabnika mora biti omogočena tudi s SimpleArbiter. Nastavi FreeRadius tako, da bo podatke o uporabnikih in geslih pobiral iz baze MySQL z imenom {MYSQL_DB_NAME}. Podatkovna shema (imena tabel) naj ostane privzeta. Dostop do strežnika Radius na RadiusServer s SimpleArbiter naj bo mogoč ob uporabi skrivnosti {RADIUS_SECRET}. V bazi ustvari vnos, ki bo omogočil, da se na RadiusServer s pomočjo protokola Radius avtenticira uporabnik {RADIUS_USERNAME} z geslom {RADIUS_PASSWORD}. Nastavi PAM za prijavo (login) tako, da bo dovolj, če se uporabnik na ssh predstavi z uporabniškim imenom in geslom, ki sta veljavna na FreeRadius, ne glede na /etc/shadow oziroma /etc/password. """, 'en':u""" Create two virtual machines - SimpleArbiter using the disk simpleArbiterDhcp and RadiusServer. On RadiusServer, install FreeRadius and MySQL. Create a mysql database named {MYSQL_DB_NAME}. Create a mysql user with the username {MYSQL_ADMIN_USER} and password {MYSQL_ADMIN_PASSWORD}. Make sure this user can access the database from SimpleArbiter and has administrative rights over the {MYSQL_DB_NAME} database. Set up FreeRadius so that the data about users and passwords is stored in the MySQL database. Keep the default schema (table names). Make the Radius server on RadiusServer accessible from SimpleArbiter using {RADIUS_SECRET} as the secret. Create an entry in the database which will enable a user with the username {RADIUS_USERNAME} to authenticate themself against the Radius server using the password {RADIUS_PASSWORD}. Set up PAM to enable login over ssh using a username and password which are valida on the FreeRadius server, regardless of the entries in /etc/shadow and/or /etc/password. """ } #KABOOM computers = { 'RadiusServer': { 'disks': [ { 'name': 'RadiusServer', }, #{ 'name': 'CDROM', # 'options':{'readonly': True}, # 'parts': [],# no parts, no mounting. #} ], 'network_interfaces': [{'network': 'net1'}], 'flavor': 'm1.tiny', 'config_drive': False }, 'SimpleArbiter': { 'disks': [ { 'name': 'simpleArbiterDhcp', # 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} } params_meta = { 'IP_RS': {'descriptions': {'si': 'Naslov RadiusServer'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False}, 'RADIUS_SECRET':{'descriptions': {'si': 'Skrivnost RADIUS'}, 'w': False, 'public':True, 'type': 'password', 'generated': True}, 'RADIUS_USERNAME': {'descriptions': {'si': 'Uporabniško ime'}, 'w': True, 'public':True, 'type': 'username', 'generated': False}, 'RADIUS_PASSWORD': {'descriptions': {'si': 'geslo uporabnika'}, 'w': False, 'public':True, 'type': None, 'generated': True}, 'MYSQL_DB_NAME': {'descriptions': {'si': 'Ime baze v mysql'}, 'w': False, 'public':True, 'type': None, 'generated': True}, 'MYSQL_ADMIN_USER':{'descriptions': {'si': 'Uporabniško ime za dostop do MySQL'}, 'w': False, 'public':True, 'type': 'username', 'generated': True}, 'MYSQL_ADMIN_PASSWORD': {'descriptions': {'si': 'Geslo za dostop do MySQL'}, 'w': True, 'public':True, 'type': 'password', 'generated': True}, 'MYSQL_SEED':{'descriptions': {'si': 'seed'}, 'w': False, 'public':True, 'type': None, 'generated': True}, } def task(IP_RS, RADIUS_SECRET, RADIUS_USERNAME, RADIUS_PASSWORD, MYSQL_DB_NAME, MYSQL_ADMIN_USER, MYSQL_ADMIN_PASSWORD, MYSQL_SEED): import pxssh import pexpect import random results = dict() peer_user = 'student' peer_passwd = 'vaje' r = random.Random(MYSQL_SEED) MYSQL_TEST_USER = kpov_random_helpers.username_gen(r) MYSQL_TEST_PASSWORD = kpov_random_helpers.alnum_gen(r, 7) RADIUS_NEW_PASSWORD = kpov_random_helpers.alnum_gen(r, 7) # Testiranje radius strtežnika results['Test_RadiusServer'] = pexpect.run('radtest {0} {1} {2} 1812 {3}'.format( RADIUS_USERNAME, RADIUS_PASSWORD, IP_RS, RADIUS_SECRET)) # Testiranje podatkovne base mysql mysql = pexpect.spawn('mysql -u {MYSQL_ADMIN_USER} -p{MYSQL_ADMIN_PASSWORD} -h {IP_RS}'.format(**locals())) mysql.expect("mysql>") results['mysql_login'] = mysql.before mysql.sendline('USE {MYSQL_DB_NAME}'.format(**locals())) mysql.expect("mysql>") results['database_connect'] = mysql.before mysql.sendline('SELECT UserName, Value FROM radcheck;') mysql.expect("mysql>") results['select_from_users'] = mysql.before mysql.sendline("INSERT INTO radcheck (UserName, Attribute, Value, Op) VALUES ('{MYSQL_TEST_USER}', 'Cleartext-Password', '{MYSQL_TEST_PASSWORD}', ':=');".format(**locals())) mysql.expect("mysql>") results['radtest_OK'] = pexpect.run('radtest {0} {1} {2} 1812 {3}'.format( MYSQL_TEST_USER, MYSQL_TEST_PASSWORD, IP_RS, RADIUS_SECRET)) results['radtest_NOK'] = pexpect.run('radtest {0} {1} {2} 1812 {3}'.format( MYSQL_TEST_USER, "Flügzeug", IP_RS, RADIUS_SECRET)) results['radtest_NOK'] = pexpect.run('radtest {0} {1} {2} 1812 {3}'.format( MYSQL_TEST_USER, "Flügzeug", IP_RS, RADIUS_SECRET)) sT = pxssh.pxssh() mysql.sendline("UPDATE radcheck SET value='{RADIUS_NEW_PASSWORD}' where UserName='{RADIUS_USERNAME}' and Attribute='Cleartext-Password';".format(**locals())) sT.login(IP_RS, RADIUS_USERNAME, RADIUS_NEW_PASSWORD) results['login_test'] = sT.before mysql.sendline("UPDATE radcheck SET value='{RADIUS_PASSWORD}' where UserName='{RADIUS_USERNAME}' and Attribute='Cleartext-Password';".format(**locals())) mysql.expect('mysql>') mysql.sendline("DELETE FROM radcheck where UserName='{MYSQL_TEST_USER}' and Attribute='Cleartext-Password';".format(**locals())) mysql.expect('mysql>') mysql.sendline('\q'); # Testiranje PAM s testnim uporabnikom return results def gen_params(user_id, params_meta): params = dict() r = random.Random(user_id) params['RADIUS_SECRET'] = kpov_random_helpers.alnum_gen(r, 8) params['RADIUS_PASSWORD'] = kpov_random_helpers.alnum_gen(r, 8) params['RADIUS_USERNAME'] = kpov_random_helpers.username_gen(r) params['MYSQL_ADMIN_USER'] = kpov_random_helpers.alnum_gen(r, 6) params['MYSQL_ADMIN_PASSWORD'] = kpov_random_helpers.alnum_gen(r, 6) params['MYSQL_DB_NAME'] = kpov_random_helpers.alnum_gen(r, 4) params['MYSQL_SEED'] = str(r.random()) return params def task_check(results, params): import re import pickle score = 0 hints = [] r = random.Random(params['MYSQL_SEED']) MYSQL_TEST_USER = kpov_random_helpers.username_gen(r) MYSQL_TEST_PASSWORD = kpov_random_helpers.alnum_gen(r, 7) RADIUS_NEW_PASSWORD = kpov_random_helpers.alnum_gen(r, 7) s = "Sending Access-Request of id [0-9]+ to {IP_RS} port 1812\r\n\tUser-Name = \"{RADIUS_USERNAME}\"\r\n\tUser-Password = \"{RADIUS_PASSWORD}\".*Access-Accept packet from host {IP_RS}".format(**params) #with open('test.pickle', 'w') as f: # pickle.dump({'pattern': s, 'res': results['Test_RadiusServer']}, f) if re.search(s, results['Test_RadiusServer'], flags=re.DOTALL): # print "Test OK" score += 2 else: print (results['Test_RadiusServer'], s) # Testiranje podatkovne base mysql s = "Welcome to the MySQL monitor.*Type 'help;' or '\\\\h' for help\\. Type '\\\\c' to clear the current input statement\\.\r\n" if re.search(s, results['mysql_login'], flags=re.DOTALL): # print "mysql_login OK" score += 1 else: print (results['mysql_login'], s) s = " USE {MYSQL_DB_NAME}\r\nReading table information.*Database changed\r\n".format(**params) if re.search(s, results['database_connect'], flags=re.DOTALL): # print "database_connect OK" score += 1 else: print (results['database_connect'],) s = " SELECT UserName, Value FROM radcheck;\r\n.*{RADIUS_USERNAME} *| *{RADIUS_PASSWORD}".format(**params) if re.search(s, results['select_from_users'], flags=re.DOTALL): # print "select_from_users OK" score += 2 else: print (results['select_from_users'], ) s = "Sending Access-Request of id [0-9]+ to {0} port 1812\r\n\tUser-Name = \"{1}\"\r\n\tUser-Password = \"{2}\".*Access-Accept packet from host {0}".format(params['IP_RS'], MYSQL_TEST_USER, MYSQL_TEST_PASSWORD) if re.search(s, results['radtest_OK'], flags=re.DOTALL): # print "radtest_OK OK" score += 2 else: print (s, results['radtest_OK']) s = "Sending Access-Request of id [0-9]+ to {0} port 1812\r\n\tUser-Name = \"{1}\"\r\n\tUser-Password = \"Flügzeug\".*rad_recv: Access-Reject packet from host {0}".format(params['IP_RS'], MYSQL_TEST_USER) if re.search(s, results['radtest_NOK'], flags=re.DOTALL): # print "radtest_NOK OK" score += 1 else: print (results['radtest_NOK'], s) s = "{RADIUS_USERNAME}@.*:~\\$".format(**params) if re.search(s, results['login_test'], flags=re.DOTALL): # print "login_test OK" score += 1 else: print (results['login_test'],s) return score, hints def prepare_disks(templates, params): # d = templates['simpleArbiterDhcp'] pass