summaryrefslogtreecommitdiff
path: root/tasks
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@fri.uni-lj.si>2019-02-24 21:05:27 +0100
committerTimotej Lazar <timotej.lazar@fri.uni-lj.si>2019-02-24 21:05:27 +0100
commit8081a5520a441b43a8a7a73f3a90c7aacfaa8e10 (patch)
treec7f49bd33ed19d53afc0ee9df8b2c82c200c5910 /tasks
parent9963b74f777edf985540eac71b1ca095f88b8bca (diff)
Move everything one level up
Diffstat (limited to 'tasks')
-rw-r--r--tasks/basic_network_gcc/task.py279
-rw-r--r--tasks/copy_rename_100_files/task.py120
-rw-r--r--tasks/copy_rename_20_files_tail_env/howtos/en/index.html18
-rw-r--r--tasks/copy_rename_20_files_tail_env/howtos/si/index.html38
-rw-r--r--tasks/copy_rename_20_files_tail_env/solution/solution.py92
-rw-r--r--tasks/copy_rename_20_files_tail_env/solution/solution.sh40
-rw-r--r--tasks/copy_rename_20_files_tail_env/task.py351
-rw-r--r--tasks/custom_rdate/CustomRDate.java21
-rw-r--r--tasks/custom_rdate/TejoLicen/rServe.zipbin0 -> 499 bytes
-rw-r--r--tasks/custom_rdate/howtos/en/index.html65
-rw-r--r--tasks/custom_rdate/howtos/images/bu1.pngbin0 -> 979 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu15.pngbin0 -> 679 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu2.pngbin0 -> 826 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu3.pngbin0 -> 13656 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu4.pngbin0 -> 1564 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu5.pngbin0 -> 11278 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu6.pngbin0 -> 15244 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu7.pngbin0 -> 3842 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu8.pngbin0 -> 3420 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/bu9.pngbin0 -> 4245 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/predvaja_clip_image003.gifbin0 -> 686 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/s1.pngbin0 -> 700 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/s2.pngbin0 -> 3882 bytes
-rw-r--r--tasks/custom_rdate/howtos/images/s3.pngbin0 -> 3569 bytes
-rw-r--r--tasks/custom_rdate/howtos/si/index.html67
-rw-r--r--tasks/custom_rdate/rDate.java34
-rw-r--r--tasks/custom_rdate/rDate.py18
-rw-r--r--tasks/custom_rdate/task.py146
-rw-r--r--tasks/dhcp_dns_predefined_ip/task.py116
-rw-r--r--tasks/edit_find_grep_compile_convert/task.py313
-rw-r--r--tasks/entrance_exam/task.py2
-rw-r--r--tasks/isc_dhcp_live_boot/howtos/en/index.html172
-rw-r--r--tasks/isc_dhcp_live_boot/howtos/en/indexEN.html172
-rw-r--r--tasks/isc_dhcp_live_boot/howtos/en/indexEN.html.save0
-rw-r--r--tasks/isc_dhcp_live_boot/howtos/images/01.pngbin0 -> 651056 bytes
-rw-r--r--tasks/isc_dhcp_live_boot/howtos/images/02.pngbin0 -> 216256 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/03.pngbin0 -> 174489 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/04.pngbin0 -> 87256 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/05.pngbin0 -> 67924 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/06.pngbin0 -> 57607 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/07.pngbin0 -> 77169 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/08.pngbin0 -> 12705 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/09.pngbin0 -> 196595 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/10.pngbin0 -> 226002 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/11.pngbin0 -> 75165 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/12.pngbin0 -> 13295 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/13.pngbin0 -> 152206 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/14.pngbin0 -> 148800 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/15.pngbin0 -> 15686 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/16.pngbin0 -> 181602 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/17.pngbin0 -> 95401 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/18.pngbin0 -> 17634 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/19.pngbin0 -> 101570 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/20.pngbin0 -> 18593 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/21.pngbin0 -> 116971 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/22.pngbin0 -> 7869 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/23.pngbin0 -> 208008 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/24.pngbin0 -> 226191 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/25.pngbin0 -> 97681 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/26.pngbin0 -> 215513 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/27.pngbin0 -> 216817 bytes
-rwxr-xr-xtasks/isc_dhcp_live_boot/howtos/images/28.pngbin0 -> 100288 bytes
-rw-r--r--tasks/isc_dhcp_live_boot/howtos/si/index.html147
-rw-r--r--tasks/isc_dhcp_live_boot/task.py222
-rw-r--r--tasks/ldap_import/task.py106
-rw-r--r--tasks/ldap_search/howtos/en/Pic1.jpgbin0 -> 182463 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic2.1.jpgbin0 -> 160469 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic2.2.jpgbin0 -> 154389 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic2.3.jpgbin0 -> 157859 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.1.jpgbin0 -> 64216 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.2.jpgbin0 -> 76701 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.3.jpgbin0 -> 65002 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.4.jpgbin0 -> 63397 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.5.jpgbin0 -> 73509 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.6.jpgbin0 -> 78701 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.7.jpgbin0 -> 57151 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic3.8.jpgbin0 -> 63569 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic4.jpgbin0 -> 111844 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic5.jpgbin0 -> 129138 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic6.jpgbin0 -> 146213 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic7.jpgbin0 -> 64296 bytes
-rw-r--r--tasks/ldap_search/howtos/en/Pic8.jpgbin0 -> 56538 bytes
-rw-r--r--tasks/ldap_search/howtos/en/index.html74
-rw-r--r--tasks/ldap_search/howtos/images/1.pngbin0 -> 179319 bytes
-rw-r--r--tasks/ldap_search/howtos/images/2.pngbin0 -> 71542 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic1.jpgbin0 -> 182463 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic2.1.jpgbin0 -> 160469 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic2.2.jpgbin0 -> 154389 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic2.3.jpgbin0 -> 157859 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.1.jpgbin0 -> 64216 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.2.jpgbin0 -> 76701 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.3.jpgbin0 -> 65002 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.4.jpgbin0 -> 63397 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.5.jpgbin0 -> 73509 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.6.jpgbin0 -> 78701 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.7.jpgbin0 -> 57151 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic3.8.jpgbin0 -> 63569 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic4.jpgbin0 -> 111844 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic5.jpgbin0 -> 129138 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic6.jpgbin0 -> 146213 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic7.jpgbin0 -> 64296 bytes
-rw-r--r--tasks/ldap_search/howtos/images/Pic8.jpgbin0 -> 56538 bytes
-rw-r--r--tasks/ldap_search/howtos/si/index.html23
-rw-r--r--tasks/ldap_search/task.py210
-rw-r--r--tasks/mock_entrance_exam/howtos/en/index.html0
-rw-r--r--tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface1.jpgbin0 -> 211527 bytes
-rw-r--r--tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface2.jpgbin0 -> 213524 bytes
-rw-r--r--tasks/mock_entrance_exam/howtos/images/SimpleArbiter.jpgbin0 -> 217218 bytes
-rw-r--r--tasks/mock_entrance_exam/howtos/images/student-entrance-interface1.jpgbin0 -> 193759 bytes
-rw-r--r--tasks/mock_entrance_exam/howtos/images/student-entrance-interface2.jpgbin0 -> 195110 bytes
-rw-r--r--tasks/mock_entrance_exam/howtos/images/student-entrance.jpgbin0 -> 217218 bytes
-rw-r--r--tasks/mock_entrance_exam/howtos/si/index.html82
-rw-r--r--tasks/mock_entrance_exam/task.py313
-rw-r--r--tasks/nat_port_forward/task.py172
-rw-r--r--tasks/nat_vlc/howtos/en/index.html72
-rw-r--r--tasks/nat_vlc/howtos/images/1.jpgbin0 -> 35092 bytes
-rw-r--r--tasks/nat_vlc/howtos/images/2.jpgbin0 -> 40962 bytes
-rw-r--r--tasks/nat_vlc/howtos/si/index.html80
-rw-r--r--tasks/nat_vlc/task.py126
-rw-r--r--tasks/nat_vlc/video.py37
-rw-r--r--tasks/network_boot_custom_program/task.py119
-rw-r--r--tasks/openvpn_multiple_hops/task.py317
-rw-r--r--tasks/openvpn_simple_smb/howtos/en/index.html98
-rw-r--r--tasks/openvpn_simple_smb/howtos/si/index.html95
-rw-r--r--tasks/openvpn_simple_smb/task.py261
-rw-r--r--tasks/openwrt/task.py103
-rw-r--r--tasks/public_ip_ssh/task.py52
-rw-r--r--tasks/public_ssh_motd_http/task.py105
-rw-r--r--tasks/radius_multiple_realms/task.py110
-rw-r--r--tasks/radius_mysql_pam/howtos/en/index.html34
-rw-r--r--tasks/radius_mysql_pam/howtos/si/index.html40
-rw-r--r--tasks/radius_mysql_pam/task.py212
-rw-r--r--tasks/rdate_64bit/task.py104
-rw-r--r--tasks/rename_grep_network/task.py282
-rw-r--r--tasks/set_ip_dhcp_hostname/task.py100
-rw-r--r--tasks/set_ip_static_dhcp/howtos/en/index.html73
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/04.pngbin0 -> 11706 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/09.pngbin0 -> 187608 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/10.pngbin0 -> 193147 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/11.pngbin0 -> 189272 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/12.pngbin0 -> 163954 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/13.pngbin0 -> 175600 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/images/17.pngbin0 -> 7062 bytes
-rw-r--r--tasks/set_ip_static_dhcp/howtos/si/index.html74
-rw-r--r--tasks/set_ip_static_dhcp/task.py127
-rw-r--r--tasks/set_motd/howtos/en/index.html44
-rw-r--r--tasks/set_motd/howtos/images/first.pngbin0 -> 3793 bytes
-rw-r--r--tasks/set_motd/howtos/images/img1.pngbin0 -> 64082 bytes
-rw-r--r--tasks/set_motd/howtos/images/img10.pngbin0 -> 27789 bytes
-rw-r--r--tasks/set_motd/howtos/images/img11.pngbin0 -> 2090 bytes
-rw-r--r--tasks/set_motd/howtos/images/img12.pngbin0 -> 4119 bytes
-rw-r--r--tasks/set_motd/howtos/images/img2.pngbin0 -> 64618 bytes
-rw-r--r--tasks/set_motd/howtos/images/img3.pngbin0 -> 63941 bytes
-rw-r--r--tasks/set_motd/howtos/images/img4.pngbin0 -> 54840 bytes
-rw-r--r--tasks/set_motd/howtos/images/img5.pngbin0 -> 12233 bytes
-rw-r--r--tasks/set_motd/howtos/images/img6.pngbin0 -> 33093 bytes
-rw-r--r--tasks/set_motd/howtos/images/img7.pngbin0 -> 32530 bytes
-rw-r--r--tasks/set_motd/howtos/images/img8.pngbin0 -> 17532 bytes
-rw-r--r--tasks/set_motd/howtos/images/img9.pngbin0 -> 23007 bytes
-rw-r--r--tasks/set_motd/howtos/images/second.pngbin0 -> 25542 bytes
-rw-r--r--tasks/set_motd/howtos/images/slika3.pngbin0 -> 21635 bytes
-rw-r--r--tasks/set_motd/howtos/images/slika4.pngbin0 -> 17317 bytes
-rw-r--r--tasks/set_motd/howtos/si/index.html46
-rw-r--r--tasks/set_motd/task.py86
-rw-r--r--tasks/smb_nfs/howtos/en/index.html341
-rw-r--r--tasks/smb_nfs/howtos/images/parameters.pngbin0 -> 8403 bytes
-rw-r--r--tasks/smb_nfs/howtos/si/index.html71
-rw-r--r--tasks/smb_nfs/task.py138
-rw-r--r--tasks/snmp_agent_uptime/howtos/en/index.html319
-rw-r--r--tasks/snmp_agent_uptime/howtos/images/01.pngbin0 -> 67779 bytes
-rw-r--r--tasks/snmp_agent_uptime/howtos/si/index.html308
-rw-r--r--tasks/snmp_agent_uptime/task.py224
-rw-r--r--tasks/snmp_alarms_interfaces/task.py107
-rw-r--r--tasks/vlc_stream_rtp/howtos/en/index.html94
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/1.pngbin0 -> 8681 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/playlist.PNGbin0 -> 48064 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/stream_finish.PNGbin0 -> 57437 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/stream_menu.pngbin0 -> 80030 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/stream_open.PNGbin0 -> 62759 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/stream_output.PNGbin0 -> 53770 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/images/stream_transcoding.PNGbin0 -> 88906 bytes
-rw-r--r--tasks/vlc_stream_rtp/howtos/si/index.html93
-rw-r--r--tasks/vlc_stream_rtp/task.py110
183 files changed, 8015 insertions, 0 deletions
diff --git a/tasks/basic_network_gcc/task.py b/tasks/basic_network_gcc/task.py
new file mode 100644
index 0000000..b23c060
--- /dev/null
+++ b/tasks/basic_network_gcc/task.py
@@ -0,0 +1,279 @@
+# 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': '''\
+<p>
+Postavite dva navidezna računalnika: <em>SimpleArbiter</em> in <em>Student</em>. Oba naj bosta povezana na internet. Poleg tega mora biti <em>Student</em> na naslovu <code>{{student_IP}</code> dostopen s <em>SimpleArbiter</em>.
+
+<p>
+Računajte, da se na <em>Student</em> ob zagonu zažene program <code>{{net_prog_name}</code>,
+ki vam spreminja nastavitve mrežne kartice.
+
+<p>
+V domačem imeniku uporabnika <code>student</code> obstaja program <code>{{P_c}</code> v programskem jeziku C. Prevedite ga v program z imenom <code>{{P_executable}</code>. Izvorna koda je namenoma pokvarjena tako, da so vanjo vrinjeni nepotrebni znaki.
+Pred prevajanjem jo morate popraviti.
+
+<p>
+Napišite skripto ali program <code>{{P_script}</code> v domačem imeniku uporabnika <code>student</code>, ki
+
+<ul>
+<li>požene <code>{{P_executable}</code> z argumentom <code>{{arg_c}</code> in mu na standardni vhod pripelje vrednost spremenljivke <code>{{env_c}</code>;
+<li>vse, kar <code>{{P_executable}</code> izpiše na <code>stderr</code>, spravi v datoteko <code>{{out_stderr_c}</code>;
+<li>vse vrstice, ki jih <code>{{P_executable}</code> izpiše na <code>stdout</code> in vsebujejo zaporedje znakov <code>ma</code>, zapiše v <code>{{out_stdout_c}</code>.
+</ul>
+
+<p>
+Lastnik vseh ustvarjenih datotek mora biti uporabnik <code>student</code>. Gesla uporabnika student (<code>vaje</code>) ne smete spreminjati.
+''',
+ 'en': '''
+''',
+}
+
+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'}],
+ 'config_drive': True,
+ }
+}
+
+networks = {
+ 'net1': {
+ 'public': True,
+ },
+ 'net2': {
+ 'public': False,
+ },
+}
+
+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_stdout', 'cat {}'.format(out_stdout_c)),
+ ('script_stderr', 'cat {}'.format(out_stderr_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 = []
+ 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
+ )
+ 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])
+ if expected_script_stdout != results['script_stdout'].strip():
+ 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<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+/* Odstranite vse odvecne velike crke Q, W ali X in program se bo prevedel. */
+
+int main(int argc, char **argv){
+ unsigned char *arg;
+ unsigned char var[255];
+ int i, arg_len, env_len, r;
+ scanf("%s", var);
+ arg = argv[1];
+ arg_len = strlen(argv[1]);
+ env_len = strlen(var);
+ r = 0;
+ for (i = 0; i<100; i++){
+ printf("%c", 32 + (arg[i % arg_len] ^ var[i % env_len]) % 64);
+ r += (int)arg[i % arg_len] + (int)var[i % env_len] + i;
+ if (i % 17 == 0){
+ printf("RAUS\\n");
+ }
+ if (i % 29 == 0){
+ printf("ma");
+ }
+ fprintf(stderr, "%c", (r % 31) + 'A');
+ if (i % 23 == 0){
+ fprintf(stderr, "PATACIS\\n");
+ }
+ }
+ printf("\\n");
+ fprintf(stderr, "\\n");
+ return r % 16;
+}
+'''
+ evil_shell_source = """#!/bin/bash -e
+{ while true; do
+ ifconfig eth1 10.0.4.19 2> /dev/null;
+ ifconfig eth0 10.0.4.20 2> /dev/null;
+ ifconfig eth2 10.0.4.21 2> /dev/null;
+ sleep 10;
+done; }&
+"""
+ import random
+ d = templates['student-entrance']
+ r = random.Random(task_params['c_destroy_gen_seed'])
+ destroyed_c_source = c_source[:110]
+ for c in c_source[110:]:
+ i = r.randint(0, 5)
+ if i == 1:
+ destroyed_c_source += 'QW'
+ if i == 2:
+ destroyed_c_source += 'XW'
+ if i == 3:
+ destroyed_c_source += 'QX'
+ destroyed_c_source += c
+ d.write(task_params['P_c'], destroyed_c_source)
+ d.chown(1000, 1000, task_params['P_c'])
+ sh_path = r.choice(['/usr/share/doc', '/var/lib', '/usr/local/share', '/etc/alternatives'])
+ sh_file = sh_path + '/' + task_params['net_prog_name']
+ d.write(sh_file, evil_shell_source)
+ d.chmod(0o775, sh_file)
+ d.write("/etc/rc.local", """#!/bin/sh -e
+export PATH=$PATH:{}
+{} &
+
+exit 0
+""".format(sh_path, task_params['net_prog_name']))
diff --git a/tasks/copy_rename_100_files/task.py b/tasks/copy_rename_100_files/task.py
new file mode 100644
index 0000000..9dcf69a
--- /dev/null
+++ b/tasks/copy_rename_100_files/task.py
@@ -0,0 +1,120 @@
+# 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':"""
+<pre>Ustvari dva navidezna računalnika. Za prvega uporabi sliko diska simpleArbiterDhcp. Na drugem računalniku
+ustvari uporabnika test z geslom test.
+Na sliki diska simpleArbiterDhcp najdeš imenik s 100 datotekami. Prekopiraj vse datoteke na drugi računalnik v domači imenik uporabnika test.
+Spremeni vsebino datotek tako, da vse male črke spremeniš v velike. Poskrbi, da se bo s prvega računalnika (simpleArbiterDhcp) mogoče prek
+ssh prijaviti na drugi računalnik in prebrati predelane datoteke.</pre>
+""",
+ 'en': '''
+<pre>Create two virtual machines. For the first, use the `simpleArbiterDhcp' image.
+On the second machine, create a user `test' with the password `test'.
+The `simpleArbiterDhcp' disk image contains a folder with 100 files. Copy all
+of these files to the other computer into the home folder of theuser `test'.
+Modify the content of these files by converting all lowercase letters into
+uppercase. Make sure that the first machine (`simpleArbiterDhcp') can use ssh
+to access the second machine and read the processed files.</pre>
+''',
+}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ {
+ 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1',
+ },
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False,
+ }
+}
+
+networks = {
+ 'net1': {
+ 'public': True,
+ },
+}
+
+params_meta = {
+ 'folder': {
+ 'descriptions': {
+ 'si': 'Mapa, ki vsebuje 100 datotek',
+ 'en': 'A folder with 100 files',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'dirname',
+ 'generated': False,
+ },
+ 'host': {
+ 'descriptions': {
+ 'si': 'Naslov racunalnika, na katerega kopiramo datoteke',
+ 'en': 'The address of the computer to which the files are copied',
+ },
+ 'w': True,
+ 'public': True,
+ 'type': 'IP',
+ 'generated': False,
+ },
+}
+
+def task(host, folder):
+ return kpov_util.ssh_test(host, 'test', 'test', (
+ ('files', 'ls -1'), # XXX: file may have newlines
+ ('contents', 'cat *'), # XXX: may include other files in $HOME
+ ))
+
+def gen_params(user_id, params_meta):
+ pass
+
+def task_check(results, params):
+ import os
+
+ score = 0
+ hints = []
+ if results['ssh'] is not True:
+ hints += ['ssh failed: ' + results['ssh']]
+
+ matched = 0
+ files = os.listdir(params['folder'])
+ for fn in files:
+ if fn in results['files'].splitlines():
+ matched += 1
+ if matched > 0:
+ score = 1
+ else:
+ hints += ["no files"]
+ if matched > len(files)/2:
+ score += 2
+ else:
+ hints += ["less than half the files"]
+ if (matched == len(files)):
+ score += 3
+ else:
+ hints += ["wrong number of files"]
+ rl = results['contents'].splitlines()
+ rl.sort()
+ tl = []
+ for fn in files:
+ with open(os.path.join(params['folder'], fn)) as f:
+ tl += f.read().upper().splitlines()
+ tl.sort()
+ if rl == tl:
+ score += 4
+ else:
+ hints += ["wrong files"]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ pass
diff --git a/tasks/copy_rename_20_files_tail_env/howtos/en/index.html b/tasks/copy_rename_20_files_tail_env/howtos/en/index.html
new file mode 100644
index 0000000..b1008cc
--- /dev/null
+++ b/tasks/copy_rename_20_files_tail_env/howtos/en/index.html
@@ -0,0 +1,18 @@
+<html>
+<body>
+<h2>Purpose of this exercise</h2>
+ <p>To learn how to use a few BASH commands.</p>
+<h2>Quick summary</h2>
+ <p>You will use bash commands like: mv, grep, env etc.</p>
+<h2>Instructions</h2>
+
+<h2><ol>
+ <li>Log into your system and in your home folder you will find a directory called Mapa containing 20 files.</li>
+ <li>Rename all files, by replacing all minus signs with underscores using the command: "rename 's/-/_/' *".</li>
+ <li>Remove all files from /home/user/mapa/mojimenik into /home/user/novi using command: "mkdir-p /home/user/novi && mv /home/user/mapa/mojimenik/* /home/user/novi"</li>
+ <li>Write all regular files containing a string "mama" into file "mama.txt", and all errors in file "napake.txt" by using: "find . -type f | grep mama 1> mama.txt 2> napake.txt".</li>
+ <li>Inspect /var/log/syslog for 5 seconds and in case a string"zmeda" appears in syslog, write "imam ga". Also while inspecting syslog, reduce the counter by every second using a command: "for i in 5 4 3 2 1; do echo $i; echo $(sed -n "$i p" /var/log/syslog | grep zmeda > /dev/null && echo "imam ga"); sleep 1; done".</li>
+ <li>Set a variable TEST to the same value as the variable USER + the number of environmen variables not containing string "TEST" in their names, by adding ~/.bashrc to the end of the file: "export TEST=$USER" + "$(env | grep -v TEST | wc -l)"</li>
+</ol></h2>
+</body>
+</html>
diff --git a/tasks/copy_rename_20_files_tail_env/howtos/si/index.html b/tasks/copy_rename_20_files_tail_env/howtos/si/index.html
new file mode 100644
index 0000000..1ce8b44
--- /dev/null
+++ b/tasks/copy_rename_20_files_tail_env/howtos/si/index.html
@@ -0,0 +1,38 @@
+<html>
+<body>
+
+<!--
+Prijavi se na sistem.
+V domači mapi najdeš imenik Mapa z 20 datotekami.
+ - preimenuj vse datoteke tako, da zamenjaš minuse s podčrtaji
+ - Napiši čim krajši ukaz, ki vse datoteke iz /home/user/mapa/mojimenik premakne v /home/user/novi
+ - Napiši ukaz, ki s pomočjo ukaza grep v datoteko "mama.txt" izpiše vse navadne (ne skrite) datoteke v trenutnem imeniku, ki vsebujejo niz "mama", v datoteko "napake.txt" pa izpiše vse morebitne napake (npr. to, da so nekateri objekti v trenutnem imeniku dejansko imeniki ali napačne simbolične povezave)
+ - Napiši ukaz, ki bo 5s sledil vsebini /var/log/syslog. V primeru, da se v syslogu pojavi niz "zmeda", naj program izpiše "imam ga". Poleg tega naj program med sledenjem syslog-u odšteva od 5 do 1 (vsako sekundo naj se izpiše naslednja številka.
+ - Nastavi okoljsko spremenljivko TEST, da bo imela isto vrednost kot okoljska spremenljivka USER + število okoljskih spremenljivk, ki v imenu ali vrednosti ne vsebujejo besede TEST. Primer: polz37
+-->
+<!--
+English
+Log into the system.
+in the home directory find the directory Mapa with 20 files.
+ -rename all the files in a such a manner that u replace al the minuses with an underscore
+ -write the shortest command possible to move all the files from /home/user/mapa/mojimenik to home/user/novi
+ -write a command which (with the help of the command grep) in the file "mama.txt" writes all the normal files (not hidden) in the current directory that contain the word "mama", and any mistakes to the file "napake.txt" (such as that the files are actually directories or wrong symbolic links)
+ -write a command which will follow the content of /var/log/syslog for 5s. In the case that the expresion "zmeda" appears in the syslog print out "imam ga". Also for every second of following the syslog print out the a number, counting down from 5 to 1.
+ -set the environment variable TEST, so it has the same value as the environmental variable USER + the number of invironmental variables which in their name do not contain the word TEST (example: polz37)
+-->
+<h2>Namen vaje</h2>
+ <p>Naučite se uporabe nekaj BASH ukazov.</p>
+<h2>Naloga na hitro</h2>
+ <p>Uporabljali boste BASH ukaze kot so: mv, grep, env in druge.</p>
+<h2>Navodila</h2>
+
+<h2><ol>
+ <li>Prijavite se v sistem. V domačem imeniku najdete imenik Mapa z 20 datotekami.</li>
+ <li>Preimenujete vse datoteke tako, da zamenjate minuse s podčrtaji z ukazom: "rename 's/-/_/' *".</li>
+ <li>Premaknite vse datoteke /home/user/mapa/mojimenik v /home/user/novi z ukazom: "mkdir-p /home/user/novi && mv /home/user/mapa/mojimenik/* /home/user/novi"</li>
+ <li>V datoteko "mama.txt" zapišite vse navadne datoteke v trenutnem imeniku, ki vsebujejo niz "mama", v datoteko "napake.txt" pa zapišite vse morebitne napake z ukazom: "find . -type f | grep mama 1> mama.txt 2> napake.txt".</li>
+ <li>Sledite vsebini /var/log/syslog za 5 sekund in v primeru, da se v syslogu pojavi niz "zmeda", izpišite "imam ga". Poleg tega med sledenjem syslog-u odštevajte od 5 do 1 z ukazom: "for i in 5 4 3 2 1; do echo $i; echo $(sed -n "$i p" /var/log/syslog | grep zmeda > /dev/null && echo "imam ga"); sleep 1; done".</li>
+ <li>Nastavite okoljsko spremenljivko TEST, da bo imela isto vrednost kot okoljska spremenljivka USER + število okoljskih spremenljivk, ki v imenu ali vrednosti ne vsebujejo besede TEST tako, da na koncu datoteke ~/.bashrc dodate: "export TEST=$USER" + "$(env | grep -v TEST | wc -l)"</li>
+</ol></h2>
+</body>
+</html>
diff --git a/tasks/copy_rename_20_files_tail_env/solution/solution.py b/tasks/copy_rename_20_files_tail_env/solution/solution.py
new file mode 100644
index 0000000..f661c4d
--- /dev/null
+++ b/tasks/copy_rename_20_files_tail_env/solution/solution.py
@@ -0,0 +1,92 @@
+# preimenuj vse datoteke tako, da zamenjaš minuse s podčrtaji
+def rename():
+ import os
+ for filename in os.listdir('.'):
+ os.rename(filename, filename.replace('-', '_'))
+
+# Napiši čim krajši ukaz, ki vse datoteke iz /home/user/mapa/mojimenik premakne v /home/user/novi
+def mv_novi():
+ import os
+ for filename in os.listdir("/home/user/mapa/mojimenik/"):
+ os.rename('/home/user/mapa/mojimenik/' + filename, '/home/user/novi/' + filename)
+
+# Napiši ukaz, ki s pomočjo ukaza grep v datoteko "mama.txt" izpiše vse navade (ne skrite) datoteke v trenutnem imeniku, ki vsebujejo niz "mama", v datoteko "napake.txt" pa izpiše vse morebitne napake (npr. to, da so nekateri objekti v trenutnem imeniku dejansko imeniki ali napačne simbolične povezave)
+def mama():
+ import os
+ import re
+ import mmap
+ mama = ''
+ wrong = ''
+ for filename in os.listdir('.'):
+ try:
+ f = open(filename, 'r+')
+ data = mmap.mmap(f.fileno(), 0)
+ if re.search('mama', data):
+ mama = mama + filename + "\n"
+ except ValueError:
+ wrong = wrong + filename + "\n"
+ open('mama.txt', 'w').write(mama)
+ open('napake.txt', 'w').write(wrong)
+
+# Napiši ukaz, ki bo 5s sledil vsebini /var/log/syslog. V primeru, da se v syslogu pojavi niz "zmeda", naj program izpiše "imam ga". Poleg tega naj program med sledenjem syslog-u odšteva od 5 do 1 (vsako sekundo naj se izpiše naslednja številka.
+def checker():
+ import time
+ import re
+ import mmap
+ t = time.time() * 1000
+ n = t
+
+ f = open('/var/log/syslog', 'r+')
+ data = mmap.mmap(f.fileno(), 0)
+ me = re.findall('zmeda', data)
+
+ c = len(me)
+ for i in range(5, 0, -1):
+ print(i)
+ n += 1000
+ while n > t:
+ f = open('/var/log/syslog', 'r+')
+ data = mmap.mmap(f.fileno(), 0)
+ me = re.findall('zmeda', data)
+ if len(me) > c:
+ c = len(me)
+ print('imam ga')
+ t = time.time() * 1000
+
+# Nastavi okoljsko spremenljivko TEST, da bo imela isto vrednost kot okoljska spremenljivka USER + število okoljskih spremenljivk, ki v imenu ali vrednosti ne vsebujejo besede TEST. Primer: polz37
+def env():
+ import os
+ import re
+ c = 0
+ for i in os.environ:
+ if not (re.search('TEST', i) or re.search('TEST', os.environ[i])):
+ c = c + 1
+ os.environ['TEST'] = os.environ['USER'] + repr(c)
+
+# S pomočjo programa cURL shrani vsebino spletne strani www.google.com v datoteko z imenom website.txt
+def googl():
+ import urllib.request
+ open('website.txt', 'w').write(urllib.request.urlopen('http://www.google.com').read())
+
+# Napiši ukaz, ki bo število pojavitev značke <div> v datoteki website.txt dodal na konec te iste datoteke brez, da bi se ukaz zapisal v zgodovino ukazov "bash history"
+def div():
+ import re
+ import mmap
+ f = open('website.txt', 'r+')
+ data = mmap.mmap(f.fileno(), 0)
+ me = re.findall('<[^/<>]*div[^>]*>', data)
+ open('website.txt', 'a+').write(repr(len(me)))
+
+# Napiši ukaz brez uporabe programa cron, kateri 5 minut po izvedbi izpiše vsebino imenika v katerem se trenutno nahajaš
+def sleep():
+ import time
+ import os
+ time.sleep(300)
+ print(os.listdir('.'))
+
+# Napiši najkrajši ukaz, ki s pomočjo Pythona zažene preprost (integriran) HTTP strežnik kateri streže datoteke iz imenika iz katerega je bil pognan na vratih 8000
+def server():
+ import http.server
+ import socketserver
+ httpd = socketserver.TCPServer(("", 8000), http.server.SimpleHTTPRequestHandler)
+ httpd.serve_forever()
diff --git a/tasks/copy_rename_20_files_tail_env/solution/solution.sh b/tasks/copy_rename_20_files_tail_env/solution/solution.sh
new file mode 100644
index 0000000..b8e2d13
--- /dev/null
+++ b/tasks/copy_rename_20_files_tail_env/solution/solution.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# preimenuj vse datoteke tako, da zamenja minuse s podrtaji
+rename 'y/-/_/' *
+
+# Napii im kraji ukaz, ki vse datoteke iz /home/user/mapa/mojimenik premakne v /home/user/novi
+mv /home/user/mapa/mojimenik/* /home/user/novi/
+
+# Napii ukaz, ki s pomojo ukaza grep v datoteko "mama.txt" izpie vse navade (ne skrite) datoteke v trenutnem imeniku, ki vsebujejo niz "mama", v datoteko "napake.txt" pa izpie vse morebitne napake (npr. to, da so nekateri objekti v trenutnem imeniku dejansko imeniki ali napane simboline povezave)
+grep -l 'mama' * 1>mama.txt 2>napake.txt
+
+# Napii ukaz, ki bo 5s sledil vsebini /var/log/syslog. V primeru, da se v syslogu pojavi niz "zmeda", naj program izpie "imam ga". Poleg tega naj program med sledenjem syslog-u odteva od 5 do 1 (vsako sekundo naj se izpie naslednja tevilka.
+COUNT=$(grep 'zmeda' /var/log/syslog | wc -l );
+END=$(date +%s%N | cut -b1-13);
+for i in {5..1}; do
+ END=$(($END + 1000));
+ echo "$i";
+ while [ $(date +%s%N | cut -b1-13) -lt $END ]; do
+ COUN1=$(grep 'zmeda' /var/log/syslog | wc -l );
+ if [ $COUN1 -gt $COUNT ]; then
+ echo "imam ga";
+ COUNT=$COUN1;
+ fi
+ done
+done
+
+# Nastavi okoljsko spremenljivko TEST, da bo imela isto vrednost kot okoljska spremenljivka USER + tevilo okoljskih spremenljivk, ki v imenu ali vrednosti ne vsebujejo besede TEST. Primer: polz37
+TEST="$USER$(printenv | grep -v TEST | wc -l)"; export TEST
+
+# S pomojo programa cURL shrani vsebino spletne strani www.google.com v datoteko z imenom website.txt
+curl http://www.google.com > website.txt
+
+# Napii ukaz, ki bo tevilo pojavitev znake <div> v datoteki website.txt dodal na konec te iste datoteke brez, da bi se ukaz zapisal v zgodovino ukazov "bash history"
+grep -o "<[^/<>]*div[^>]*>" website.txt | wc -l >> website.txt; history -d $((HISTCMD-1))
+
+# Napii ukaz brez uporabe programa cron, kateri 5 minut po izvedbi izpie vsebino imenika v katerem se trenutno nahaja
+$(sleep 300; ls) &
+
+# Napii najkraji ukaz, ki s pomojo Pythona zaene preprost (integriran) HTTP strenik kateri stree datoteke iz imenika iz katerega je bil pognan na vratih 8000
+python -m SimpleHTTPServer \ No newline at end of file
diff --git a/tasks/copy_rename_20_files_tail_env/task.py b/tasks/copy_rename_20_files_tail_env/task.py
new file mode 100644
index 0000000..ce51c9c
--- /dev/null
+++ b/tasks/copy_rename_20_files_tail_env/task.py
@@ -0,0 +1,351 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si': '''\
+<p>
+Prijavi se na sistem kot uporabnik <code>student</code> z geslom <code>vaje</code>.
+
+<p>
+V domači mapi najdeš imenik <code>{{file_rename_dirname}}</code> z 20 datotekami. Preimenuj vse datoteke tako, da zamenjaš minuse s podčrtaji.
+
+<p>
+Napiši najkrajši ukaz v <code>bash</code>, ki vse datoteke iz imenika <code>{{mv_src_dir}}</code> premakne v imenik <code>{{mv_dst_dir}}</code>. Ukaz spravi v <code>/home/student/mv_ukaz</code>. Pazite, da bodo ob testiranju v izvornem imeniku <em>iste</em> datoteke, kot so bile, ko je bila virtualka nova, ciljni imenik pa bo prazen. To pomeni, da boste verjetno morali po vsakem testiranju datoteke premakniti nazaj. Za krajšanje ukaza lahko izkoristite imeni imenikov.
+
+<p>
+Napiši ukaz, ki s pomočjo ukaza <code>grep</code> v datoteko <code>~/mama.txt</code> izpiše imena vseh navadnih (ne skritih) datotek v trenutnem imeniku, ki vsebujejo niz <code>mama</code>, v datoteko <code>~/napake.txt</code> pa izpiše vse morebitne napake (npr. to, da so nekateri objekti v trenutnem imeniku dejansko imeniki ali napačne simbolične povezave). Ukaz spravite v datoteko <code>/home/student/mama_ukaz</code>.
+
+<p>
+Napiši program (lahko v <code>bash</code>), ki bo pet sekund sledil vsebini <code>/var/log/syslog</code>. V primeru, da se v syslogu pojavi niz <code>zmeda</code>, naj program izpiše <code>imam ga</code>. Poleg tega naj program med sledenjem syslog-u odšteva od 5 do 1 (vsako sekundo naj se izpiše naslednja številka). Program naj bo v <code>/home/student/syslog_ukaz.sh</code>.
+
+<p>
+Namesti paket <code>cowsay</code> in ga preizkusi. 😊
+
+<p>
+S pomočjo programa <code>curl</code> preštej število pojavitev niza <code>images</code> v spletni strani, ki jo dobiš na naslovu <code>http://localhost/{{curl_fname}}</code> na <em>malishell</em> in število zapiši v spremenljivko <code>$images</code> na <em>simpleArbiterDhcpGW</em> v lupini, kjer poganjaš <code>task_check.py</code>.
+
+<p>
+V imeniku <code>{{wc_dirname}}</code> najdeš datoteko <code>count.txt</code>. Preštej število prehodov v novo vrstico v <code>count.txt</code> in rezultat zapiši v novo datoteko <code>lines.txt</code> v istem imeniku.
+''',
+ 'en': '''\
+<p>
+Log into the system as <code>student</code> using <code>vaje</code> as your password.
+
+<p>
+In your home folder you will find a directory called <code>{{file_rename_dirname}}</code> containing 20 files. Rename all files in that directory replacing all dashes with underscores
+
+<p>
+Find the shortest command for copying all the files located in <code>{{mv_src_dir}}</code> into the folder <code>{{mv_dst_dir}}</code>. Create a shell script <code>/home/student/mv_ukaz</code> containing this command. Before running <code>test_task.py</code>, make sure <code>{{mv_src_dir}}</code> contains the same files as when you downloaded your virtual disk. This probably means that you will have to move the files back from <code>{{mv_dst_dir}}</code> to <code>{{mv_src_dir}}</code> after each test.
+
+<p>
+Come up with a command or sequence of commands in bash which will, using <code>grep</code>, write the names all normal (not hidden) files which contain the string <code>mama</code> and are located in the working directory (<code>pwd</code>) into the file <code>~/mama.txt</code> while writing errors such as files in current directory being folders or symbolic links in the file called <code>napake.txt</code>. Write this command to <code>/home/student/mama_ukaz</code>.
+
+<p>
+Write a program (which may be a shell script) that will track the contents of <code>/var/log/syslog</code> for five seconds. Every time an entry containing the string <code>zmeda</code> appears in the syslog, the script should output <code>imam ga</code>. In addition, the script should count down from 5 to 1 with a one-second interval. Store the script in <code>/home/student/syslog_ukaz.sh</code>.
+
+<p>
+Install the package <code>cowsay</code> and test it. 😊
+
+<p>
+Using the <code>curl</code> command count the number of occurences of the string <code>images</code> on the web page accessible from <em>malishell</em> at <code>http://localhost/{{curl_fname}}</code>. On <em>simpleArbiterDhcpGW</em> within the shell where you are running <code>test_task.py</code>, set the environment variable <code>$images</code> to this number.
+
+<p>
+In the directory <code>{{wc_dirname}}</code> there is a file called <code>count.txt</code>. Write the number of newlines in this file into the file <code>lines.txt</code> in the same directory.
+''',
+}
+
+computers = {
+ 'malishell': {
+ 'disks': [
+ { 'name': 'malishell',
+ },
+ #{ 'name': 'CDROM',
+ # 'options':{'readonly': True},
+ # 'parts': [],# no parts, no mounting.
+ #}
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiterDhcpGW': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGW',
+ # attempt automount
+ },
+ #{ 'name': 'CDROM',
+ # 'options': {'readonly': True},
+ # 'parts': [{'dev': 'b1', 'path': '/cdrom'}],
+ #},
+ ],
+ 'network_interfaces': [{'network': 'test-net'}, {'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = {'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_malishell': {'descriptions': {'si': 'Naslov malishell'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'file_creator_random_seed': {'descriptions': {'si': 'random file creator seed'}, 'w': False, 'public':False, 'type': None, 'generated': True},
+ 'file_rename_dirname': {'descriptions': {'si': 'imenik z datotekami, ki naj se jih preimenuje'}, 'w': False, 'public':True, 'type': 'dirname', 'generated': True},
+ 'mv_src_dir': {'descriptions': {'si': 'imenik, iz katerega premakni datoteke'}, 'w': False, 'public':True, 'type': 'dirname', 'generated': True},
+ 'mv_dst_dir': {'descriptions': {'si': 'imenik, v katerega premakni datoteke'}, 'w': False, 'public':True, 'type': 'dirname', 'generated': True},
+ 'cowsay_string': {'descriptions': {'si': 'Kaj rece krava?'}, 'w': False, 'public':True, 'type': 'short', 'generated': True},
+ 'syslog_n_zmeda': {'descriptions': {'si': 'st. zapisov zmeda v 5s'}, 'w': False, 'public':True, 'type': 'uint', 'generated': True},
+ 'curl_fname': {'descriptions': {'si': 'ime datoteke, dostopne prek http'}, 'w': False, 'public':True, 'type': 'filename', 'generated': True},
+ 'curl_n_images': {'descriptions': {'si': 'n pojavitev niza images'}, 'w': False, 'public':False, 'type': 'integer', 'generated': True},
+ 'wc_dirname': {'descriptions': {'si': 'imenik, v katerem je datoteka count.txt'}, 'w': False, 'public':True, 'type': 'dirname', 'generated': True},
+ 'wc_n_lines': {'descriptions': {'si': 'n vrstic v count.txt'}, 'w': False, 'public':False, 'type': 'integer', 'generated': True},
+}
+
+def task(IP_malishell, file_rename_dirname, mv_src_dir, mv_dst_dir, cowsay_string, curl_fname, wc_dirname):
+ import collections
+ import os
+
+ # TOD: (polz) this has to be changed! Get a move on!
+ #
+ # sv: Z primozem lavricem sva skusala nekaj narediti
+ # Ker gen params ni narejen, sklepam da je "Mapa" na namizju,
+ # imena datotek pa so: 1,1-,2,2-,3,3-,4,5,6,7,8,9,.mama1,mama2,mama3,mama4,mama5,mojimenik,novi,oce1
+ # v mojimenik se nahaja mojimenikfile
+ # mama2 vsebuje "mama"
+ #Stirje subt-aski dodani.By Mihec.
+ results = kpov_util.ssh_test(IP_malishell, 'student', 'vaje', (
+ ('preimenuj', '/bin/ls -a1 {}'.format(file_rename_dirname)),
+ ('pre_mv_src', '/bin/ls -a1 {}'.format(mv_src_dir)),
+ ('pre_mv_dst', '/bin/ls -a1 {}'.format(mv_dst_dir)),
+ ('mv_ls_size', '/bin/ls -l ~/mv_ukaz'),
+ (None, '. ~/mv_ukaz'),
+ ('post_mv_src', '/bin/ls -a1 {}'.format(mv_src_dir)),
+ ('post_mv_dst', '/bin/ls -a1 {}'.format(mv_dst_dir)),
+
+ # mama_ukaz
+ (None, 'cd /home/student/grep_test_dir'),
+ (None, '. ~/mama_ukaz'),
+ ('grep_napake', 'cat ~/napake.txt'),
+ ('grep_mama', 'cat ~/mama.txt'),
+
+ # sledenje syslog
+ (None, 'date'),
+ ('syslog_start_time', '/usr/local/bin/syslog_spammer &'),
+ ('syslog_result', '/home/student/syslog_ukaz.sh'),
+ ('syslog_end_time', 'date'),
+
+ ('cowsay', 'cowsay "{}"'.format(cowsay_string)),
+ ('wc_origfile', 'cat {}/count.txt'.format(wc_dirname)),
+ ('wc_lines', 'cat {}/lines.txt'.format(wc_dirname)),
+ ))
+
+ try:
+ results['curl_env'] = os.environ['images']
+ except:
+ results['curl_env'] = ''
+
+ #results['curl'] = subprocess.check_output(["cat","/home/student/Desktop/website.txt"])
+ #results['chkimages'] = subprocess.check_output(["curl www.24ur.com >> dlg.txt && cat dlg.txt | grep -c ","images"])
+ #results['count'] = subprocess.check_output(["wc","/home/student/Desktop/count.txt"])
+ #results['lines'] = subprocess.check_output(["cat","/home/student/Desktop/lines.txt"])
+ #results['cowsay'] = subprocess.check_output(["dpkg --get-selections | grep","cowsay"])
+
+ return results
+
+def gen_params(user_id, params_meta):
+ import random
+ import subprocess
+ params = dict()
+ homedir = '/home/student/'
+ r = random.Random(user_id)
+ params['file_creator_random_seed'] = str(r.random())
+ params['file_rename_dirname'] = homedir + kpov_util.default_generators['dirname'](r)
+ params['mv_src_dir'] = homedir + "".join([r.choice("abcdefgh") for i in range(6)])
+ params['mv_dst_dir'] = homedir + "".join([r.choice("ijklmnop") for i in range(6)])
+ params['syslog_n_zmeda'] = str(r.randint(5, 15))
+ params['cowsay_string'] = kpov_util.default_generators['short_text'](r)
+ params['curl_fname'] = kpov_util.default_generators['filename'](r)
+ params['curl_n_images'] = str(r.randint(30,100))
+ params['wc_dirname'] = homedir + "".join([r.choice("rstuvxz") for i in range(8)])
+ params['wc_n_lines'] = str(r.randint(200, 600))
+ #params['images'] = subprocess.check_output(["echo","$images"])
+ return params
+
+def task_check(results, params):
+ import re
+ import random
+ score = 0
+ hints = []
+ r = random.Random(params['file_creator_random_seed'])
+ fnames = []
+ for i in range(20):
+ fnames.append("".join([ r.choice("_abcdefghijk") for j in range(8)]))
+ #TO FINISH SCORING WE REQUIRE DICT KEYS AND FUNCTIONS gen_params AND task TO BE FINISHED
+
+ # preimenuj 1
+ task1_ok = True
+ for fname in fnames:
+ task1_ok = task1_ok and results['preimenuj'].find(fname) > 0
+ if task1_ok:
+ score += 2
+ else:
+ hints += ["wrong dash rename"]
+
+ # premakni datoteke s cim krajsim ukazom
+ fnames = []
+ try:
+ for i in range(40):
+ fnames.append("".join([ r.choice("123456789abcdefghijk") for j in range(8)]))
+ task2_re = re.search(
+ r"-rw[x-][r-][w-][x-][r-][w-][x-] \d* student student (\d*) .*mv_ukaz",
+ results['mv_ls_size'])
+ mv_ls_size = int(task2_re.group(1))
+ task2_ok = mv_ls_size <= 17 and mv_ls_size > 2
+ except:
+ task2_ok = False
+ if task2_ok:
+ score += 1
+ else:
+ hints += ["wrong mv_command size or owner"]
+
+ # rename files
+ pre_src = set([i.strip() for i in results['pre_mv_src'].splitlines()[2:]])
+ pre_dst = set([i.strip() for i in results['pre_mv_dst'].splitlines()[2:]])
+ print(set(fnames))
+ print(pre_src)
+ task2_ok = task2_ok and pre_src == set(fnames)
+ task2_ok = task2_ok and len(pre_dst) < 3
+ post_src = set([i.strip() for i in results['post_mv_src'].splitlines()[2:]])
+ post_dst = set([i.strip() for i in results['post_mv_dst'].splitlines()[2:]])
+ task2_ok = task2_ok and post_dst == set(fnames)
+ task2_ok = task2_ok and len(post_src) < 3
+ if task2_ok:
+ score += 1
+ else:
+ hints += ["wrong rename files"]
+
+ # mama_ukaz
+ task3_ok = True
+ mama_fnames = []
+ for i in range(20):
+ mama_fnames.append("".join([ r.choice("123456789abcdefghijk") for j in range(8)]))
+ papa_fnames = []
+ for i in range(20):
+ papa_fnames.append("".join([ r.choice("123456789abcdefghijk") for j in range(8)]))
+ dirnames = []
+ for i in range(20):
+ dirnames.append("".join([ r.choice("123456789abcdefghijk") for j in range(8)]))
+ linknames = []
+ for i in range(20):
+ linknames.append("".join([ r.choice("123456789abcdefghijk") for j in range(8)]))
+ for i in dirnames + linknames + papa_fnames:
+ if (i not in papa_fnames) and results['grep_napake'].find(i) < 0:
+ task3_ok = False
+ if results['grep_mama'].find(i) >= 0:
+ task3_ok = False
+ for i in papa_fnames:
+ if results['grep_napake'].find(i) >= 0:
+ task3_ok = False
+ if results['grep_mama'].find(i) >= 0:
+ task3_ok = False
+ for i in mama_fnames:
+ if results['grep_mama'].find(i) < 0:
+ task3_ok = False
+ if task3_ok:
+ score += 2
+ else:
+ hints += ["mama cries"]
+
+ # sledenje syslog
+ #print( results['syslog_start_time'])
+ #print( results['syslog_result'])
+ #print( results['syslog_end_time'])
+ # syslog count
+ # TODO: check syslog
+ task4_ok = True
+ if task4_ok:
+ score += 1
+ else:
+ hints += ["wrong syslog count"]
+
+ task5_ok = True
+ try:
+ assert int(results['curl_env'].strip()) == int(params['curl_n_images'])
+ except:
+ task5_ok = False
+ if task5_ok:
+ score += 2
+ else:
+ hints += ["wrong image count"]
+ task6_ok = True
+ try:
+ assert int(results['wc_lines'].strip()) == int(params['wc_n_lines'])
+ except:
+ task6_ok = False
+ if task6_ok:
+ score += 1
+ else:
+ hints += ["wrong line count"]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ import random
+ d = templates['malishell']
+ r = random.Random(task_params['file_creator_random_seed'])
+ # rename
+ d.mkdir(task_params['file_rename_dirname'])
+ d.chown(1000, 1000, task_params['file_rename_dirname'])
+ for i in range(20):
+ fname = task_params['file_rename_dirname'] + '/' + "".join(
+ [r.choice("-abcdefghijk") for j in range(8)])
+ d.touch(fname)
+ d.chown(1000, 1000, fname)
+ # mv ukaz
+ d.mkdir(task_params['mv_src_dir'])
+ d.chown(1000, 1000, task_params['mv_src_dir'])
+ for i in range(40):
+ fname = task_params['mv_src_dir'] + '/' +"".join(
+ [r.choice("123456789abcdefghijk") for j in range(8)])
+ d.touch(fname)
+ d.chown(1000, 1000, fname)
+ d.mkdir(task_params['mv_dst_dir'])
+ d.chown(1000, 1000, task_params['mv_dst_dir'])
+ # grep mama
+ # mama fnames
+ d.mkdir('/home/student/grep_test_dir')
+ for i in range(20):
+ d.write("/home/student/grep_test_dir/" + "".join(
+ [ r.choice("123456789abcdefghijk") for j in range(8)]),
+ "mama")
+ # papa fnames
+ for i in range(20):
+ d.write("/home/student/grep_test_dir/" + "".join(
+ [ r.choice("123456789abcdefghijk") for j in range(8)]),
+ "papa")
+ # dirnames
+ for i in range(20):
+ d.mkdir("/home/student/grep_test_dir/" + "".join(
+ [ r.choice("123456789abcdefghijk") for j in range(8)]))
+ # linknames
+ for i in range(20):
+ d.ln_sf("mali zeleni", "/home/student/grep_test_dir/" + "".join(
+ [ r.choice("123456789abcdefghijk") for j in range(8)]))
+ # sledenje syslog
+ spammer_source = "#!/bin/sh\n" + int(task_params['syslog_n_zmeda']) * "logger zmeda\n"
+ d.write("/usr/local/bin/syslog_spammer", spammer_source)
+ d.chmod(0o775, "/usr/local/bin/syslog_spammer")
+ # curl
+ l1 = ['images'] * int(task_params['curl_n_images'])
+ l2 = ['imeges'] * r.randint(30, 100)
+ lx = l1 + l2
+ r.shuffle(lx)
+ d.write("/var/www/html/{}".format(task_params['curl_fname']), ''.join(lx))
+ # wc
+ lx = ['\n']*int(task_params['wc_n_lines'])
+ lx += ['a', 'b', 'c', 'repa', 'in', 'krompir',
+ 'raus', 'e', 'patacis'] * r.randint(50, 150)
+ r.shuffle(lx)
+ d.mkdir(task_params['wc_dirname'])
+ d.chown(1000, 1000, task_params['wc_dirname'])
+ d.write("{}".format(os.path.join(task_params['wc_dirname'], 'count.txt')), "".join(lx))
+
+ write_default_config(templates['simpleArbiterDhcpGW'], global_params)
diff --git a/tasks/custom_rdate/CustomRDate.java b/tasks/custom_rdate/CustomRDate.java
new file mode 100644
index 0000000..426dece
--- /dev/null
+++ b/tasks/custom_rdate/CustomRDate.java
@@ -0,0 +1,21 @@
+import java.io.InputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.Date;
+
+public class CustomRDate {
+ public static void main(String main[]) throws Exception{
+ try {
+ Socket s = new Socket("ntp1.arnes.si", 37);
+ InputStream vhod = s.getInputStream();
+ byte podatek[] = new byte[8];
+ int dejanskoPrebranih = vhod.read(podatek, 4, 4);
+ ByteBuffer buf = ByteBuffer.wrap(podatek);
+ long stevilka = buf.getLong() - 2208988800L;
+ Date d = new Date(stevilka*1000);
+ System.out.println(d);
+ } catch(Exception e) {
+ System.out.println("Nedosegljiv streznik.");
+ }
+ }
+} \ No newline at end of file
diff --git a/tasks/custom_rdate/TejoLicen/rServe.zip b/tasks/custom_rdate/TejoLicen/rServe.zip
new file mode 100644
index 0000000..9061692
--- /dev/null
+++ b/tasks/custom_rdate/TejoLicen/rServe.zip
Binary files differ
diff --git a/tasks/custom_rdate/howtos/en/index.html b/tasks/custom_rdate/howtos/en/index.html
new file mode 100644
index 0000000..18ebfc1
--- /dev/null
+++ b/tasks/custom_rdate/howtos/en/index.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <style>
+ img{
+ margin:10px 0px 10px 0px;
+ }
+ </style>
+</head>
+
+<body>
+ <h1>Custom rdate</h1>
+ <h2>Short preview:</h2>
+ Set time on server using rdate. Write a program that converts 32-bit numbers into a readable time format.</p>
+ <h2>Instructions:</h2>
+ 1. Downlaod Student.vdi (client) and SimpleArbiter.vdi (server) from the virtual machine images folder<br>
+ 2. Use VirtualBox (or similar) to create two virtual machines, select the virtual disk images from the previous step as hard drives<br>
+ 3. Run both virtual machines.<br>
+ 4. Login on client user:<strong> root</strong> pass:<strong> kaboom </strong> and server user:<strong> tester</strong> pass:<strong> tester</strong></p>
+ <img src="../images/bu15.png">
+ <img src="../images/bu1.png">
+ <h3>First part: update time using rdate.</h3>
+ <p>
+ 1. Find and remember your server IP address. (ifconfig)<br><img src="../images/bu2.png"><br><img src="../images/bu3.png"><br>
+ 2. Install rdate with <strong>sudo apt-get install</strong> rdate<br>
+ 3. On Student client use rdate to update the machine time <strong>rdate SERVER_IP</strong><br><img src="../images/bu4.png"><br>
+ Note: It's NOT an error if the updated time does not match the correct time.<br>
+ </p>
+ <h3>Second part: write a program that converts 32bit numbers into a readable time format.</h3>
+ <p>
+ You can write a program in Java or Python using your favourite text editor.
+ </p>
+ <h4>Java</h4>
+ <p>
+ 1. We use <strong>nano guliver.java</strong> to create a new blank file<br>
+ 2. Write a program that converts 32bit numbers into a readable time format.<br>
+ <img src="../images/bu6.png"><br><img src="../images/bu7.png"><br>
+ 3. Press Ctrl+X, then Y and Enter to save the program<br>
+ 4. In case you don't have java installed use <strong>sudo apt-get install openjdk-6-jdk</strong><br>
+ <img src="../images/predvaja_clip_image003.gif"><br>
+ 5. To compile use <strong>javac bintodec3.java</strong><br>
+ 6. Run the created program with <strong>java guliver</strong> and input the server IP or name...<br>
+ <img src="../images/bu9.png"><br>
+ </p>
+ <h4>Python</h4>
+ 1. Use nano guliver.py to create a new empty python file.<br>
+ 2. Write a program that converts 32bit numbers into a readable time format.<br>
+ <img src="../images/bu5.png"><br>
+ 3. Press Ctrl+X, then Y and Enter to save our program<br>
+ 4. Run the created program with <strong>python guliver.py</strong><br><img src="../images/bu8.png"><br>
+ </p>
+ <h3>Testing</h3>
+ <p>
+ 1. Use command ./run_test.py to run the tester<br>
+ <img src="../images/s1.png"><br>
+ 2. Your username and password are the same as on ucilnica (npr.: "pz1234@student.uni-lj.si" in "geslo123").<br>
+ <img src="../images/s2.png"> <img src="../images/s3.png"> <br>
+ 3. Name of the task should look like 09.predvaja.<br>
+ 4. When prompted for file path insert your program path (example: if bintodec3.py is in the same folder as program run_test.py run with ./bintodec3.py).<br>
+ 5. Then input your server IP address (SimpleArbiterRDate).<br>
+ 6. If all goes well the program should give you an OK that means you've completed your task successfully.
+ </p>
+</body>
+</html>
diff --git a/tasks/custom_rdate/howtos/images/bu1.png b/tasks/custom_rdate/howtos/images/bu1.png
new file mode 100644
index 0000000..c6eeac8
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu1.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu15.png b/tasks/custom_rdate/howtos/images/bu15.png
new file mode 100644
index 0000000..c2ac808
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu15.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu2.png b/tasks/custom_rdate/howtos/images/bu2.png
new file mode 100644
index 0000000..85fcfa8
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu2.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu3.png b/tasks/custom_rdate/howtos/images/bu3.png
new file mode 100644
index 0000000..831e764
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu3.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu4.png b/tasks/custom_rdate/howtos/images/bu4.png
new file mode 100644
index 0000000..495351a
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu4.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu5.png b/tasks/custom_rdate/howtos/images/bu5.png
new file mode 100644
index 0000000..103e0e6
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu5.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu6.png b/tasks/custom_rdate/howtos/images/bu6.png
new file mode 100644
index 0000000..b032223
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu6.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu7.png b/tasks/custom_rdate/howtos/images/bu7.png
new file mode 100644
index 0000000..bd50500
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu7.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu8.png b/tasks/custom_rdate/howtos/images/bu8.png
new file mode 100644
index 0000000..98f7812
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu8.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/bu9.png b/tasks/custom_rdate/howtos/images/bu9.png
new file mode 100644
index 0000000..9ed78ce
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/bu9.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/predvaja_clip_image003.gif b/tasks/custom_rdate/howtos/images/predvaja_clip_image003.gif
new file mode 100644
index 0000000..02be389
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/predvaja_clip_image003.gif
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/s1.png b/tasks/custom_rdate/howtos/images/s1.png
new file mode 100644
index 0000000..52b6ee5
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/s1.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/s2.png b/tasks/custom_rdate/howtos/images/s2.png
new file mode 100644
index 0000000..78a65ce
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/s2.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/images/s3.png b/tasks/custom_rdate/howtos/images/s3.png
new file mode 100644
index 0000000..c32eae1
--- /dev/null
+++ b/tasks/custom_rdate/howtos/images/s3.png
Binary files differ
diff --git a/tasks/custom_rdate/howtos/si/index.html b/tasks/custom_rdate/howtos/si/index.html
new file mode 100644
index 0000000..e68221c
--- /dev/null
+++ b/tasks/custom_rdate/howtos/si/index.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <style>
+ img{
+ margin:10px 0px 10px 0px;
+ }
+ </style>
+</head>
+
+<body>
+ <h1>Custom rdate</h1>
+ <h2>Naloga na hitro:</h2>
+ <p>
+ Nastavi uro na strežniku s pomočjo rdate. Napiši program, ki pretvori 32-bitna števila v čas.
+ </p>
+ <h2>Navodila:</h2>
+ <p>
+ 1. Z imenika s slikami virtualnih računalnikov povlecite sliki Student.vdi(klient) in SimpleArbiterRDate.vdi(strežnik).<br>
+ 2. Z VirtualBoxom (ali podobnim) ustvarite dva virtualna računalnika in jim kot disk za shranjevanje podajte Student.vdi ter SimpleArbiterRDate.vdi.<br>
+ 3. Zaženite oba navidezna računalnika.<br>
+ 4. Na Student se prijavite z uporabnikom <strong>root</strong> in geslom <strong>kaboom</strong>
+ na SimpleArbiterRDate pa z uporabnikom <strong>tester</strong> in geslom <strong>tester</strong>.
+ </p>
+ <img src="../images/bu15.png"> <img src="../images/bu1.png">
+ <h3>Prvi del naloge: posodobi uro računalnika s pomočjo rdate.</h3>
+ <p>
+ 1. Preverite in si zapišite IP naslov na SimpleArbiterRDate. (ifconfig)<br><img src="../images/bu2.png"><br><img src="../images/bu3.png"><br>
+ 2. Z ukazom <strong>sudo apt-get install</strong> rdate namestimo program rdate.<br>
+ 3. Na Student z pomočjo rdate posodobi uro računalnika. <strong>rdate IP_SIMPLE_ARBITER</strong><br><img src="../images/bu4.png"><br>
+ Opozorilo: NI napaka, če se posodobljen čas ne ujema s pravilnim časom. <br>
+ </p>
+ <h3>Drugi del naloge: napiši program, ki pretvori binarni zapis 32-bitnega števila v časovni format.</h3>
+ <p>
+ Nalogo lahko rešite v Javi ali v Pythonu. Prav tako pa lahko kodo pišete v poljubnem tekstovnem urejevalniku.</p>
+ <p>
+ <h4>Java</h4>
+ <p>
+ 1. Z ukazom nano guliver.java ustvarimo in odpremo prazen program s tekstovnim urejevalnikom nano<br>
+ 2. Napišemo program za pretvarjanje 32-bitnega števila v čas<br>
+ 3. Pritisnemo Ctrl+X, nato Y in Enter, da program zapremo in shranimo.<br>
+ 4. Če je še nimamo, naložimo Javo <strong>sudo apt-get install openjdk-6-jdk</strong><br><im src="../images/predvaja_clip_image003.gif"><br>
+ 5. Prevedemo program <strong>javac bintodec3.java</strong><br>
+ 6. Lahko ga še zaženemo ter preizkusimo <strong>java guliver</strong>.Na standardni vhod vnasemo IP naslov ali ime strežnika NTP strežnikom, ki nam pošlje 32 bitno število in pretvori v čas<br><br>
+ </p>
+ <h4>Python</h4>
+ <p>
+ 1. Z ukazom nano guliver.py ustvarimo in odpremo prazen program s tekstovnim urejevalnikom nano<br>
+ 2. Napišemo program za pretvarjanje 32-bitnega števila v čas<br>
+ 3. Pritisnemo Ctrl+X, nato Y in Enter, da program zapremo in shranimo.<br>
+ 4. Program zaženemo z ukazom <strong>python guliver.py</strong><br><img src="../images/bu8.png"><br>
+ </p>
+
+ <h3>Testiranje</h3>
+ <p>
+ 1. Lahko poženemo tester; z ukazom ./run_test.py<br>
+ <img src="../images/s1.png"><br>
+ 2. Kot "Upor. Ime" in "Geslo" napišite vaše podatke učilnice. (npr.: "pz1234@student.uni-lj.si" in "geslo123")<br>
+ <img src="../images/s2.png"> <img src="../images/s3.png"> <br>
+ 3. Kot ime naloge vpišite 09.predvaja.<br>
+ 4. Ko vas program vpraša po poti programa vnesite vašo pot do programa za pretvarjanje. (npr.: če imate program bintodec3.py v isti mapi kot program run_test.py, vnesete: ./bintodec3.py)<br>
+ 5. Povpraša tudi po IP naslovu SimpleArbiterjaRDate, vnesite.<br>
+ 6. Če je šlo vse po sreči, program vrne OK vi pa ste opravili nalogo.
+ </p>
+</body>
+</html>
diff --git a/tasks/custom_rdate/rDate.java b/tasks/custom_rdate/rDate.java
new file mode 100644
index 0000000..8c8bae7
--- /dev/null
+++ b/tasks/custom_rdate/rDate.java
@@ -0,0 +1,34 @@
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.uti.Date;
+import java.util.Scanner;
+
+public class rDate{
+
+ public static void main(String[] args) throw IOException{
+ Scanner sc=new Scanner(System.in);
+ String niz=sc.next();
+
+ try{
+ Socket s=new Socket(niz,37);
+ OutputStreamWriter izhod=new OutputStreamWriter(s.getOutputStream());
+ InputStream vhod=s.getInputStream();
+ byte[] podatek=new byte[4];
+ ByteBuffer buf=ByteBuffer.wrap(podatek);
+ int stevilka=buf.getInt();
+ long dolga=stevilka
+ long maska=-1;
+ maska =~(maska <<32);
+ dolga = dolga & maska;
+ Date d=new Date(dolga *1000 - 2208988800000L);
+ System.out.print(d);
+ izhod.write(d.toString());
+ }catch(SocketException e){
+ System.out.println("Strežnik ne obstaja");
+ }
+ }
+}
diff --git a/tasks/custom_rdate/rDate.py b/tasks/custom_rdate/rDate.py
new file mode 100644
index 0000000..97885b0
--- /dev/null
+++ b/tasks/custom_rdate/rDate.py
@@ -0,0 +1,18 @@
+
+#!/usr/bin/env python
+#-*- coding utf-8 -*-
+
+import socket
+import struct
+import time
+
+niz=input("Vnesi IP ali ime strežnika:")
+s = socket.socket(
+ socket.AF_Inet, socket.SOCK_STREAm)
+s.connect((niz,37))
+podatek = s.recv(4)
+stevilka = struct.unpack("!I", podatek)
+st= stevilka[0]-220898800
+date = time.localtime(st)
+print((time.strftime('%Y-%m-%d %H:%M:%S'), date))
+s.send(date)
diff --git a/tasks/custom_rdate/task.py b/tasks/custom_rdate/task.py
new file mode 100644
index 0000000..4c5ff9f
--- /dev/null
+++ b/tasks/custom_rdate/task.py
@@ -0,0 +1,146 @@
+# kpov_util should be imported by add_assignment.py
+
+# TODO: finish this!
+instructions = {
+ 'si': '''\
+<p>
+Postavite dva navidezna računalnika: <em>SimpleArbiterDhcpRdate</em> in <em>rdateClient</em>.
+
+<p>
+Nastavite čas na <em>rdateClient</em> tako, da kot rdate strežnik uporabite <em>SimpleArbiterDhcpRdate</em>.
+
+<p>
+Na <em>rdateClient</em> ustvarite uporabnika <code>test</code> z geslom <code>test</code>. V domačem imeniku uporabnika <code>test</code> ustvarite program z imenom <code>{{PROGRAM_FILENAME}}</code>. 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. <em lang="en">big endian</em>). Število naj program izpiše na standardni izhod v obliki niza.
+''',
+ 'en': '''\
+<p>
+Set up two virtual machines: <em>SimpleArbiterDhcpRdate</em> and <em>rdateClient</em>.
+
+<p>
+Set the time on <em>rdateClient</em> using rdate with <em>SimpleArbiterDhcpRdate</em> as
+the server.
+
+<p>
+On <em>rdateClient</em> create a user with the username <code>test</code> and password <code>test</code>. Then, write a program called <code>{{PROGRAM_FILENAME}}</code> and put it in user <code>test</code>’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)
diff --git a/tasks/dhcp_dns_predefined_ip/task.py b/tasks/dhcp_dns_predefined_ip/task.py
new file mode 100644
index 0000000..4822c2a
--- /dev/null
+++ b/tasks/dhcp_dns_predefined_ip/task.py
@@ -0,0 +1,116 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Ustvari tri navidezne računalnike. Za enega (SimpleArbiter) uporabi sliko diska simpleArbiter. Na drugega (DHCP_server) postavi strežnika DHCP in DNS in poskrbi, da ta računalnik dobi IP naslov {IP_server}. Poskrbi, da bo preostali računalnik (DHCP_client) dobil naslov {IP_client}, ki mu ga določi DHCP strežnik. Poskrbi še,da DNS strežnik vrne za hostname {HOSTNAME_X} IP naslov {IP_X}.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ #{ 'name': 'CDROM',
+ # 'options':{'readonly': True},
+ # 'parts': [],# no parts, no mounting.
+ #}
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ #{ '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_server': {'descriptions': {'si': 'IP naslov DHCP streznika'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_client': {'descriptions': {'si': 'IP naslov DHCP klienta'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'MAC_client': {'descriptions': {'si': 'MAC naslov DHCP klienta'}, 'w': True, 'public': True, 'type': 'MAC', 'generated': False},
+ 'HOSTNAME_X': {'descriptions': {'si': 'Hostname za DNS'}, 'w': False, 'public': True, 'type': 'short_text', 'generated': True},
+ 'IP_X': {'descriptions': {'si': 'Naslov, ki ga vrne DNS'}, 'w': False, 'public': False, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_server, IP_client, MAC_client, HOSTNAME_X):
+ tests = {
+ IP_server: (
+ ('dhcp_proces', 'sudo ps -A')),
+ IP_client: (
+ ('dhcp', 'sudo dhcping -s {} -h {} -c {}'.format(IP_server, MAC_client, IP_client)),
+ ('dns_hostname', 'nslookup {}'.format(HOSTNAME_X)),
+ ('client_IP', '/sbin/ifconfig')),
+ }
+
+ results = collections.defaultdict(str)
+ for host, host_tests in tests.items():
+ results.update(kpov_util.ssh_test(host, 'student', 'vaje', host_tests))
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id+"bla")
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['IP_server'], params['IP_client'], params['IP_X'] = kpov_util.IPv4_addr_gen(r, net, 3)
+ params['HOSTNAME_X'] = "".join([r.choice('ABCDEFGHIJKLMNPRSTUVZ') for i in range(5)])
+ return params
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+ if results['dhcp'].find("Got answer from: {}".format(params['IP_server'])) > -1:
+ score += 2
+ else:
+ hints += ["dhcp server IP wrong"]
+ if results['dhcp_proces'].find("dhcpd") > -1:
+ score += 2
+ else:
+ hints += ["dhcp wrong"]
+ if results['dns_hostname'].find("Address: {}".format(params['IP_X'])) >= 0:
+ score += 2
+ else:
+ hints += ['dns hostname IP wrong']
+ if results['dns_hostname'].find("Server:\t\t{}".format(params['IP_server'])) > -1:
+ score += 2
+ else:
+ hints += ['dns server IP wrong']
+ if results['client_IP'].find('inet {}'.format(params['IP_client'])) > -1:
+ score += 2
+ else:
+ hints += ['client IP wrong']
+ return score, hints
+
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
+
diff --git a/tasks/edit_find_grep_compile_convert/task.py b/tasks/edit_find_grep_compile_convert/task.py
new file mode 100644
index 0000000..deaac4f
--- /dev/null
+++ b/tasks/edit_find_grep_compile_convert/task.py
@@ -0,0 +1,313 @@
+# 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': '''\
+<p>
+Ustvari dva navidezna računalnika: <em>SimpleArbiter</em> <em>SmallStudent</em>.
+
+<p>
+Poskrbi, da bo <em>SmallStudent</em> s <em>SimpleArbiter</em> dostopen na naslovu <code>{{testip}}</code>.
+
+<p>
+Na <em>SmallStudent</em> ustvari uporabnika <code>{{testuser}}</code> z geslom <code>{{passwd}}</code>.
+
+<p>
+Na <em>SmallStudent</em> je nekje v domačem imeniku uporabnika <code>bilbo</code> skrita datoteka, ki vsebuje niz <code>{{magicstr}}</code>. Skopiraj jo v domači imenik uporabnika <code>{{testuser}}</code> in jo poimenuj <code>{{dstfile}}</code>. Poskrbi, da bo lastnik <code>{{testuser}}</code>, skupina pa naj bo enaka kot pri izvorni datoteki. Brati naj jo ima pravico samo lastnik, pisati lastnik in skupina, poganjati nihče.
+
+<p>
+V <code>{{dstfile}}</code> zamenjaj vse vrstice oblike <code>poXYZlz</code>, kjer je <code>XYZ</code> poljubno zaporedje znakov, tako, da bo namesto <code>XYZ</code> niz <code>kaka</code>.
+
+<p>
+Napiši program v poljubnem programskem jeziku, ki kot argument sprejme število B med 0 in 7. Program naj prebere znak s standardnega vhoda Če je B-ti bit v znaku nastavljen na 1, naj izpiše <code>ta</code>. Če je B-ti bit nastavljen na 0, naj program izpiše <code>ti</code>. Program poimenuj <code>{{progname}}</code> in ga spravi v domači imenik uporabnika <code>{{testuser}}</code>.
+''',
+ 'en': '''\
+<p>
+Create two virtual machines: <em>SimpleArbiter</em> and <em>SmallStudent</em>.
+
+<p>
+Make sure that <em>SmallStudent</em> is accessible from <em>SimpleArbiter</em> on IP <code>{{testip}}</code>.
+
+<p>
+Create a user <code>{{testuser}}</code> with the password <code>{{passwd}}</code> on <em>SmallStudent</em>.
+
+<p>
+There is a file containing <code>{{magicstr}}</code> hidden somewhere in the home directory of user <code>bilbo</code>. Copy it into <code>{{testuser}}</code>’s home directory and name it <code>{{dstfile}}</code>. Change the owner to <code>{{testuser}}</code> and ensure the group is the same as for the original file. Make sure only the owner has the right to read it, only the owner and group members have the right to write to it and nobody has the right to execute it.
+
+<p>
+In <code>{{dstfile}}</code>, replace all lines of the form <code>poXYZlz</code> where <code>XYZ</code> are arbitrary characters so that <code>XYZ</code> is replaced by <code>kaka</code>.
+
+<p>
+Write a program in any programming language. The program should accept a single argument B, which is a number between 0 and 7. It should read a character from standard input and output <code>ta</code> if B-th bit in this character is set to 1, and <code>ti</code>. If B-th bit is set to 0. Name the program <code>{{progname}}</code> and place it in the home directory of <code>{{testuser}}</code>.
+''',
+}
+
+# instructions = {'si': 'Potrpite.', 'en': 'Have patience.'}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ {
+ 'name': 'simpleArbiterDhcpGW',
+ },
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1',
+ },
+ {
+ 'network': 'net2',
+ },
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False,
+ },
+ 'SmallStudent': {
+ 'disks': [
+ {
+ 'name': 'student-entrance2',
+ },
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net2',
+ },
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False,
+ }
+}
+
+networks = {
+ 'net1': {
+ 'public': True,
+ },
+ 'net2': {
+ 'public': False,
+ }
+}
+
+params_meta = {
+ 'testip': {
+ 'descriptions': {
+ 'si': 'IP SmallStudent',
+ 'en': 'IP SmallStudent',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'IP',
+ 'generated': True,
+ },
+ 'testuser': {
+ 'descriptions': {
+ 'si': 'Uporabnik na SmallStudent',
+ 'en': 'Username on SmallStudent',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'username',
+ 'generated': True,
+ },
+ 'passwd': {
+ 'descriptions': {
+ 'si': 'Geslo na SmallStudent',
+ 'en': 'Password on SmallStudent',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': None,
+ 'generated': True,
+
+ },
+ 'magicstr':{
+ 'descriptions': {
+ 'si': 'Niz v iskani datoteki',
+ 'en': 'String in the file you need to find',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': None,
+ 'generated': True,
+
+ },
+ 'dstfile':{
+ 'descriptions': {
+ 'si': 'Ciljno ime datoteke',
+ 'en': 'Destination filename',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'filename',
+ 'generated': True,
+ },
+ 'progname':{
+ 'descriptions': {
+ 'si': 'Ime programa',
+ 'en': 'Program filename',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'filename',
+ 'generated': True,
+ },
+ 'pubseed':{
+ 'descriptions': {
+ 'si': 'Nekaj nepredvidenega',
+ 'en': 'A random seed',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': None,
+ 'generated': True,
+ },
+ 'rndseed':{
+ 'descriptions': {
+ 'si': 'random seed za skrito datoteko',
+ 'en': 'random seed for hiding the file',
+ },
+ 'w': False,
+ 'public': False,
+ 'type': None,
+ 'generated': True,
+ },
+}
+
+def task(testip, testuser, passwd, magicstr, dstfile, progname, pubseed):
+ import random
+
+ r = random.Random(pubseed)
+ tests = [
+ ('dst_ls', 'ls -l ~/{}'.format(dstfile)),
+ ('dst_file_contents', 'cat ~/{}'.format(dstfile)),
+ ('home_ls', 'ls ~/'.format(dstfile)),
+ ]
+
+ N_TITA = 40
+ for i in range(N_TITA):
+ b = r.randint(0, 7)
+ x = oct(r.randint(37, 127)).replace('o', '')
+ tests += [('tita-{:02}'.format(i), 'echo -e "\\{}" | ~/{} {}'.format(x, progname, b))]
+
+ results = kpov_util.ssh_test(testip, testuser, passwd, tests)
+ results['tita_return'] = ''.join(results['tita-{:02}'.format(i)] for i in range(N_TITA))
+
+ return results
+
+def gen_params(user_id, params_meta):
+ import random
+ params = dict()
+ r = random.Random(user_id)
+ params['testip'] = kpov_util.IPv4_addr_gen(r,
+ network = '10.94.80.0/19', n_generated=1)[0]
+ params['testuser'] = kpov_util.default_generators['username'](r)
+ params['passwd'] = kpov_util.alnum_gen(r, 8)
+ params['magicstr'] = "".join([r.choice("qwerztlpoQWERTPOL") for i in range(10)])
+ params['dstfile'] = kpov_util.default_generators['filename'](r)
+ params['progname'] = kpov_util.default_generators['filename'](r)
+ while params['dstfile'] == params['progname']:
+ params['progname'] = kpov_util.default_generators['filename'](r)
+ params['pubseed'] = kpov_util.alnum_gen(r, 8)
+ params['rndseed'] = kpov_util.alnum_gen(r, 8)
+ return params
+
+
+def task_check(results, params):
+ import os
+ import re
+ N_TITA = 40
+ hints = []
+ score = 0
+ r = random.Random(params['rndseed'])
+
+ if results['ssh'] is not True:
+ hints += ['ssh failed: ' + results['ssh']]
+ return score, hints
+
+ expected_contents = params['magicstr']
+ for i in range(1000):
+ start = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)])
+ mid = "".join([r.choice("uiasdfghjkyxcvbnm1234567890ASDFGHJKYZXCVBNM") for i in range(60)])
+ end = r.choice(["lz", "1z", "Iz", "iz", "l2", "I2", "12"])
+ if start[:2] == "po" and end == "lz":
+ start = "po"
+ mid = "kaka"
+ x = start + mid + end
+ expected_contents += x + "\r\n"
+ if results["dst_file_contents"] == expected_contents:
+ score += 3
+ else:
+ for i, (a, b) in enumerate(zip(expected_contents, results['dst_file_contents'])):
+ if a != b:
+ break
+ hints += ['wrong file {} at position {}'.format(params['dstfile'], i)]
+
+ expected_ls = "-rw--w---- 1 {testuser} bilbo .*{dstfile}.*\r\n".format(**params)
+ if re.match(expected_ls, results["dst_ls"]):
+ score += 3
+ else:
+ hints += ["missing file or wrong user/permissions\n" + results["dst_ls"]]
+ if results["home_ls"].find(params['progname']) > -1:
+ score += 2
+ else:
+ hints += ["missing program"]
+
+ expected_tita = ""
+ r = random.Random(params['pubseed'])
+ for i in range(N_TITA):
+ b = r.randint(0, 7)
+ x_i = r.randint(37, 127)
+ if x_i & (1 << b):
+ expected_tita += "ta"
+ else:
+ expected_tita += "ti"
+ if results["tita_return"] == expected_tita:
+ score += 2
+ else:
+ hints += ['program output incorrect:\nwanted:\t{}\ngot:\t{}'.format(expected_tita, results["tita_return"])]
+ return score, hints
+
+
+def prepare_disks(templates, task_params, global_params):
+ import random
+ import os
+
+ # first create the file contents to make it easyer to check.
+ hidden_contents = task_params['magicstr']
+ r = random.Random(task_params['rndseed'])
+ for i in range(1000):
+ x = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)])
+ x += "".join([r.choice("uiasdfghjkyxcvbnm1234567890ASDFGHJKYZXCVBNM") for i in range(60)])
+ x += r.choice(["lz", "1z", "Iz", "iz", "l2", "I2", "12"])
+ hidden_contents += x + "\n"
+
+ # create hidden file
+ dir_list = ['Qlipper', 'Thunar', 'blender', 'autostart', 'kazam', 'mc', 'netsurf', 'pulse', 'qupzilla', 'radare2', 'teamviewer', 'texstudio', 'vlc']
+ ending_list = ['rc', '.conf', '']
+ start_list = ['net', 'dev', 'doc', 'lib', 'time', 'conf']
+ r.shuffle(dir_list)
+ file_letters = ["mod", "co"]
+
+ d = templates['student-entrance2']
+ for potential_dir in dir_list:
+ try:
+ potential_dir = os.path.join('/home/bilbo/.config', potential_dir)
+ d.mkdir(potential_dir)
+ d.chown(1001, 1001, potential_dir)
+ except:
+ pass
+ for i in range(r.randint(2, 20)):
+ rndstr2 = r.choice(start_list) + \
+ r.choice(file_letters) + r.choice(ending_list)
+ hidden_file_name = os.path.join(potential_dir,
+ rndstr2)
+ d.write(hidden_file_name, hidden_contents)
+ d.chown(1001, 1001, hidden_file_name)
+ file_letters = ["stamp", "", "dev", "re"]
+ hidden_contents = "".join([r.choice("asdfghjkyxcvbnm1234567890 \n") for j in range(10000)])
+ file_letters = file_letters + ["mod", "co"]
+ # TODO create some additional files
+
+ write_default_config(templates['simpleArbiterDhcpGW'], global_params)
diff --git a/tasks/entrance_exam/task.py b/tasks/entrance_exam/task.py
new file mode 100644
index 0000000..bfefbd1
--- /dev/null
+++ b/tasks/entrance_exam/task.py
@@ -0,0 +1,2 @@
+instructions = {'si': """
+Reši pristopni kolokvij z visoko oceno.""" }
diff --git a/tasks/isc_dhcp_live_boot/howtos/en/index.html b/tasks/isc_dhcp_live_boot/howtos/en/index.html
new file mode 100644
index 0000000..63d2463
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/en/index.html
@@ -0,0 +1,172 @@
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>06 - preparation (isc_dhcp_live_boot)</title>
+ </head>
+
+ <body>
+ <h1 style="color:blue">06 - preparation (isc_dhcp_live_boot)</h1>
+ <h2>Table of contents</h2>
+ <ul>
+ <li><a href="#namen">Purpose of this exercise</a></li>
+ <li><a href="#navidezniRacunalniki">Virtual machines, needed for the purpose of exercise</a></li>
+ <li><a
+href="#skicaPodomrezja">Schematics of our subnet</a></li>
+ <li><a href="#simpleArbiterGW">Setting up simpleArbiterGW</a></li>
+ <li><a href="#DHCP">Setting up DHCP Server</a></li>
+ <li><a href="#clientA">Setting BootableClient A</a></li>
+ <li><a href="#clientB">Setting up BootableClient B</a></li>
+ </ul>
+
+
+ <h2 id="namen">Purpose of this exercise</h2>
+ <p>How to perform live boot using a DHCP server.</p>
+
+ <h2 id="navidezniRacunalniki">Virtual machines needed to perform the task.</h2>
+ <p>We need VirtualBox and the following 4 virtual
+machines:
+ <ul>
+ <li><a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterGW.vdi">simpleArbiterGW</a></li>
+ <li><a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterDhcp.vdi">DHCP Server</a></li>
+ <li>Bootable Client A (diskless
+machine)</li>
+ <li>Bootable Client B (diskless
+machine)</li>
+ </ul>
+ </p>
+
+ <h2 id="skicaPodomrezja">Schematics of our subnet</h2>
+ <img style="width: 800px; height: 610px;" src="../images/01.png" alt="slika-01"></img>
+ <p>Our goal is to make BootableClient A get it's IP
+through DHCP server and boot up using file
+A, which is located on simpleArbiterGW,</br>If we run
+BootableClient B machines, we would like it to retrieve it's IP
+through DHCP server and boot from some live ISO which is also located on
+SimpleArbiterGW.
+ </p>
+
+ <h2 id="simpleArbiterGW">Setting up <mark>simpleArbiterGW</mark></h2>
+ <p>Download <a
+href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterGW.vdi">simpleArbiterGW.vdi</a>
+and then run VirtualBox. After the file is downloaded, choose the New
+option in VirtualBoxu and set simpleArbiterGW in the Name
+field.</br>Memory size, should be set accordingly (1gb will suffice). Then choose "Use an existing virtual hard drive file" and select simpleArbiterGW.vdi clicking Create.</p>
+ </br>
+ <img style="width: 800px; height: 464px;" src="../images/02.png" alt="slika-02"></img>
+ <p>We start our virtual machines simpleArbiterGW using the
+following login
+credentials; username: "root", password: "kaboom".</br></br>
+ At the start, the computer on NAt get's it's IP(in our case 10.0.2.15).</br>(to check this use<b>ifconfig</b>) We now use this address and eth0 interface to access the internet.<p>
+ <img style="width: 800px; height: 384px;" src="../images/03.png" alt="slika-03"></img>
+ <p>However, we would like this machine to have 2
+interfaces! One on NAT(we already have this one), and the other one on Internal Network,</br>throuh which we will communicate wiht the DHCP Server and other machines on our Internal Network.</br></br>
+ We add a new interface, by turning off the virtual machine,
+select our machine in VirtualBox and select
+računalnik, ter v VirtualBoxu <b>Settings -> Network</b></br>
+ <b>Adapter</b> 1 is already set to NAT, we set <b>Adapter
+2</b> to
+Internal Network</p>
+ <img style="width: 800px; height: 137px;" src="../images/04.png" alt="slika-04"></img>
+ <p>So, now we have two network interfaces!</br>In VirtuaBox
+we can define multiple Internal Networks, however, for our needs two
+will suffice. We save the settings and restart simpleArbiterGW.</br></br>
+ What we must do now, is to assign both interfaces IP addresses. We do this by setting the<b>interfaces</b>file
+ located at<b>/etc/network</b>.</p>
+ <img style="width: 800px; height: 229px;" src="../images/05.png" alt="slika-05"></img>
+ <p>Eth0 was already handled by and integrated DHCP, so eth0 had been assigned an IP).</br>
+ We have to set up the other network interface. If we don't know it's name, we find it out using <b>ifconfig -a</b>.</p>
+ <img style="width: 800px; height: 117px;" src="../images/06.png" alt="slika-06"></img>
+ <p>We can conclude the interface names is set to Eth1.
+ Now we would like to assign an IP naslov to Eth1.</br>
+ Ifconfig could be used, but rebooting the machine would reset the settings. Which is not ideal :)</br>
+ So configuring <b>/etc/network/interfaces would be a better idea.</b></br></br>
+ Let's make up a random local network or a local area network or local area network address and assign it to eth1.
+ </p>
+ <img style="width: 800px; height: 296px;" src="../images/07.png" alt="slika-07"></img>
+ <p>We save the config file. Our machine still has no IP on eth1 so we use the <b>ifup eth1</b> command</p>
+ <img style="width: 800px; height: 23px;" src="../images/08.png" alt="slika-08"></img></br>
+ <p>Now we use the <b>ifconfig</b> command, to see whether and ip is assigned to eth1 interface</p>
+ <img style="width: 800px; height: 389px;" src="../images/09.png" alt="slika-09"></img>
+ <p>We can see the IP is set. Now let's set up the DHCP
+Server!</p>
+
+ <h2 id="DHCP">Setting up <mark>DHCP Server</mark></h2>
+ <p>We download <a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterDhcp.vdi">simpleArbiterDhcp.vdi</a> and start VirtualBox. After the file had been dowloaded we select New in VirtualBoxu and unde rthe Name tag write DHCP Server.</br>We set the Memory size accordingly(1gb of memory should be sufficient). We also select "Use an existing virtual hard drive file" and select the simpleArbiterDhcp and press Create.</p>
+ </br>
+ <img style="width: 800px; height: 464px;" src="../images/10.png" alt="slika-10"></img>
+ <p>We run DHCP Server virtual machine and login using "root" ad username and "kaboom" as password.</br></br>
+ <p>At first, our machine has no assigned IP, since none was set! Let+s configure it in <b>/etc/network/interfaces</b>.</br>But which interface should we configure? Using <b>ifconfig -a</b> command, we see it's <b>eth0</b>interface.<br>
+ Again we select our IP address.</p>
+ <img style="width: 800px; height: 283px;" src="../images/11.png" alt="slika-11"></img>
+ <p>We save the configuration file. Our computer still has no IP address assigned to eth0, so using <b>ifdown eth0</b> and then <b>ifup eth0</b>we provide one.</p>
+ <img style="width: 800px; height: 25px;" src="../images/12.png" alt="slika-12"></img>
+ <p>Now let us use <b>ifconfig</b> command, to check whether there is an IP assigned to interface eth0</p>
+ <img style="width: 800px; height: 329px;" src="../images/13.png" alt="slika-13"></img>
+ <p>We got it! We install DHCP server using <b>apt-get install isc-dhcp-server</b></p>
+ <img style="width: 800px; height: 322px;" src="../images/14.png" alt="slika-14"></img>
+ <p>We see a bunch of errors. Why? Bacause, we have no internet access! <br>
+ We need to specify the Gateway for our inteface. Our Gateway will be set as IP of our simpleArbiter virtual machine.</br> We do this using the<b>route add default gw 192.168.251.1 eth0</b> command</p>
+ <img style="width: 800px; height: 43px;" src="../images/15.png" alt="slika-15"></img>
+ <p>Try pinging Google's DNS server at 8.8.8.8, to check if now have internet access.</br>
+ We do this using the <b>ping 8.8.8.8</b> command.</p>
+ <img style="width: 800px; height: 361px;" src="../images/16.png" alt="slika-16"></img>
+ <p>Google's DNS server is responding. Great! </br>
+ However, we still cannot run <b>apt-get install isc-dhcp-server</b></br>
+ Let's tempororly add another interface and set it to NAT, so we get internet access and install the DHCP server.</br></br>
+ We add a new interface by turning off the virtual computer, in VirtualBox we select our virtual machine and then select <b>Settings -> Network</b></br>
+ <b>Adapter 1</b> has already been set to Internal Network, we set <b>Adapter 2</b> to NAT</p>
+ <img style="width: 800px; height: 134px;" src="../images/17.png" alt="slika-17"></img>
+ <p>We run DHCP Server and in file<b>/etc/network/interfaces</b> at the end of the line add <b>iface eth1 inet dhcp</b>, then save the file and run <b>ifup eth1</b>.<br>
+ Now we have access to the internet and can install our DHCP server with <b>apt-get install isc-dhcp-server install</b> command</br>
+ <img style="width: 800px; height: 26px;" src="../images/18.png" alt="slika-18"></img></br>
+ <p>Let's see what's in<b>/var/log/syslog</b>, which is a file where our system information is stored in.</p>
+ <img style="width: 800px; height: 323px;" src="../images/19.png" alt="slika-19"></img></br>
+ <p>Looks like we need to set up a DHCP server and specify where it should listen! </br>
+ DHCP settings are stored in <b>/etc/dhcp/dhcpd.conf</b>. Let's set it! </br>
+ First let's comment out <b>option domain-name-servers</b> to avoid having errors.</p>
+ <img style="width: 800px; height: 26px;" src="../images/20.png" alt="slika-20"></img></br>
+ <p>Then we configure DHCP server, so it would serve IPs a a certain subnet. We add the following lines:</p>
+ <img style="width: 800px; height: 417px;" src="../images/21.png" alt="slika-21"></img>
+ <p><b>(subnet)</b> We set the subnet and the IP range, which the DHCP server should use, and which file it should serve.</p>Some PXEs are so unintelligent, that you should specify where they should get the files from and to do that you specify next-server </br>(IP from which it will be served from, in our case simpleArbiter), we also specify gateway, which, in our case is also simpleArbiter.</br></br>Since we would like, that in the case of BootableClient B another file to be served, we do it by defining a special host like this:</br><b>(host special)</b> Under <b>hardware ethernet</b> we specifiy MAC address of our BootableClient B, we assign it a static ip and where the file <b>live-ISO</b> is located.</p>
+ <p>We save the settings and kill the process named <b>dnsmasq</b>using<b>kilall dnsmasq</b>.</p>
+ <img style="width: 740px; height: 34px;" src="../images/22.png" alt="slika-22"></img>
+ <p>We restart our DHCP server, to apply the new settings. This is done using <b>service isc-dhcp-server restart</b></br> command. DHCP server is now ready! We supply BootableClientA and BootableClientB and test them!</p>
+
+
+ <h2 id="clientA">Setting up <mark>BootableClient A</mark></h2>
+ <p>We open VirtualBox and select <b>New</b>, for the
+<b>Name</b> field we specify
+BootableClient A and for the <b>Hard drive</b> we select <b>Do not add a
+virtual
+hard drive</b> (as we want diskless device), </br>and select Create.
+We want the computer to be on Internal network so vse select our
+<b>Bootable Client
+A</b> and select </br><b>Settings->Network</b> where we change Adapter
+1 to Internal Network.</p>
+ <img style="width: 800px; height: 678px;" src="../images/23.png" alt="slika-23"></img>
+ <p>We also want our computer to boot through the network, so
+under<b>Boot Order</b>tab select <b>Network</b>.</br>
+ We save the setting by clicking <b>OK</b></p>
+ <img style="width: 800px; height: 697px;" src="../images/24.png" alt="slika-24"></img>
+ <p>We run our BootableClient-a A and it get's it's
+IP(which is great), using the DHCP server and the simpleArbiter serves
+it exactly the file we specified. <b>A.0</b></p>
+ <img style="width: 800px; height: 494px;" src="../images/25.png" alt="slika-25"></img>
+
+
+
+ <h2 id="clientB">Setting up<mark>BootableClient
+B</mark></h2>
+ <p>We open virtual box and select <b>New</b> and under the <b>Name</b> tag write BootableClient B and under the <b>Hard drive</b>tab choose <b>Do not add a virtual hard drive</b> (since we want a diskless machine), </br>and then press the Create button, which will create a virtual machine. We want our machine to be connected to out Internal network so we select <b>Bootable Client B</b> and then select </br><b>Settings->Network</b> and set the Adapter 1 to Internal Network.</br>
+ Under <b>MAC Address</b> we specify the same MAC address that is specified in the (dhcpd.conf -> host special) file, since we want our machine to be an exception</br> and will be served a special file named<b>live-ISO</b></p>
+ <img style="width: 800px; height: 678px;" src="../images/26.png" alt="slika-26"></img>
+ <p>We want our machine to perform a netboot, so under the <b>System</b></p> <b>Boot Order</b> tag specify only <b>Network</b>.</br>
+ We save the setting by clicking the <b>OK</b> button</p>
+ <img style="width: 800px; height: 697px;" src="../images/27.png" alt="slika-27"></img>
+ <p>We run our BootableClient-a A and it get's it's IP address using DHCP server and simpleArbiter serves it the file we selected called <b>live-ISO</b></p>
+ <img style="width: 800px; height: 494px;" src="../images/28.png" alt="slika-28"></img>
+
+
+ </body>
+</html>
+
diff --git a/tasks/isc_dhcp_live_boot/howtos/en/indexEN.html b/tasks/isc_dhcp_live_boot/howtos/en/indexEN.html
new file mode 100644
index 0000000..c83ed57
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/en/indexEN.html
@@ -0,0 +1,172 @@
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>06 - preparation (isc_dhcp_live_boot)</title>
+ </head>
+
+ <body>
+ <h1 style="color:blue">06 - preparation (isc_dhcp_live_boot)</h1>
+ <h2>Table of contents</h2>
+ <ul>
+ <li><a href="#namen">Purpose of this exercise</a></li>
+ <li><a href="#navidezniRacunalniki">Virtual machines, needed for the purpose of exercise</a></li>
+ <li><a
+href="#skicaPodomrezja">Schematics of our subnet</a></li>
+ <li><a href="#simpleArbiterGW">Setting up simpleArbiterGW</a></li>
+ <li><a href="#DHCP">Setting up DHCP Server</a></li>
+ <li><a href="#clientA">Setting BootableClient A</a></li>
+ <li><a href="#clientB">Setting up BootableClient B</a></li>
+ </ul>
+
+
+ <h2 id="namen">Purpose of this exercise</h2>
+ <p>How to perform live boot using a DHCP server.</p>
+
+ <h2 id="navidezniRacunalniki">Virtual machines needed to perform the task.</h2>
+ <p>We need VirtualBox and the following 4 virtual
+machines:
+ <ul>
+ <li><a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterGW.vdi">simpleArbiterGW</a></li>
+ <li><a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterDhcp.vdi">DHCP Server</a></li>
+ <li>Bootable Client A (diskless
+machine)</li>
+ <li>Bootable Client B (diskless
+machine)</li>
+ </ul>
+ </p>
+
+ <h2 id="skicaPodomrezja">Schematics of our subnet</h2>
+ <img style="width: 800px; height: 610px;" src="../images/01.png" alt="slika-01"></img>
+ <p>Our goal is to make BootableClient A get it's IP
+through DHCP server and boot up using file
+A, which is located on simpleArbiterGW,</br>If we run
+BootableClient B machines, we would like it to retrieve it's IP
+through DHCP server and boot from some live ISO which is also located on
+SimpleArbiterGW.
+ </p>
+
+ <h2 id="simpleArbiterGW">Setting up <mark>simpleArbiterGW</mark></h2>
+ <p>Download <a
+href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterGW.vdi">simpleArbiterGW.vdi</a>
+and then run VirtualBox. After the file is downloaded, choose the New
+option in VirtualBoxu and set simpleArbiterGW in the Name
+field.</br>Memory size should be set accordingly (1gb will suffice). Then choose "Use an existing virtual hard drive file" and select simpleArbiterGW.vdi clicking Create.</p>
+ </br>
+ <img style="width: 800px; height: 464px;" src="../images/02.png" alt="slika-02"></img>
+ <p>We start our virtual machines simpleArbiterGW using the
+following login
+credentials; username: "root", password: "kaboom".</br></br>
+ At the start, the computer on NAt get's it's IP(in our case 10.0.2.15).</br>(to check this use<b>ifconfig</b>) We now use this address and eth0 interface to access the internet.<p>
+ <img style="width: 800px; height: 384px;" src="../images/03.png" alt="slika-03"></img>
+ <p>However, we would like this machine to have 2
+interfaces! One on NAT(we already have this one), and the other one on Internal Network,</br>throuh which we will communicate wiht the DHCP Server and other machines on our Internal Network.</br></br>
+ We add a new interface, by turning off the virtual machine,
+select our machine in VirtualBox and select
+računalnik, ter v VirtualBoxu <b>Settings -> Network</b></br>
+ <b>Adapter</b> 1 is already set to NAT, we set <b>Adapter
+2</b> to
+Internal Network</p>
+ <img style="width: 800px; height: 137px;" src="../images/04.png" alt="slika-04"></img>
+ <p>So, now we have two network interfaces!</br>In VirtuaBox
+we can define multiple Internal Networks, however, for our need's two
+will suffice. We save the settings and restart simpleArbiterGW.</br></br>
+ What we must do now, is to assign both interfaces IP addresses. We do this by setting the<b>interfaces</b>file
+ located at<b>/etc/network</b>.</p>
+ <img style="width: 800px; height: 229px;" src="../images/05.png" alt="slika-05"></img>
+ <p>Eth0 was already handled by and integrated DHCP, so eth0 had been assigned an IP).</br>
+ We have to set up the other network interface. If we don't know it's name, we find it out using <b>ifconfig -a</b>.</p>
+ <img style="width: 800px; height: 117px;" src="../images/06.png" alt="slika-06"></img>
+ <p>We can conclude the interface names is set to Eth1.
+ Now we would like to assign an IP naslov to Eth1.</br>
+ Ifconfig could be used, but rebooting the machine would reset the settings. Which is not ideal :)</br>
+ So configuring <b>/etc/network/interfaces would be a better idea.</b></br></br>
+ Let's make up a random local network or a local area network or local area network address and assign it to eth1.
+ </p>
+ <img style="width: 800px; height: 296px;" src="../images/07.png" alt="slika-07"></img>
+ <p>We save the config file. Our machine still has no IP on eth1 so we use the <b>ifup eth1</b> command</p>
+ <img style="width: 800px; height: 23px;" src="../images/08.png" alt="slika-08"></img></br>
+ <p>Now we use the <b>ifconfig</b> command, to see whether and ip is assigned to eth1 interface</p>
+ <img style="width: 800px; height: 389px;" src="../images/09.png" alt="slika-09"></img>
+ <p>We can see the IP is set. Now let's set up the DHCP
+Server!</p>
+
+ <h2 id="DHCP">Setting up <mark>DHCP Server</mark></h2>
+ <p>We download <a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterDhcp.vdi">simpleArbiterDhcp.vdi</a> ter zaženemo VirtualBox. Ko je datoteka prenesena v VirtualBoxu izberemo New ter v polje Name vpišemo DHCP Server.</br>Ustrezno nastavimo tudi Memory size (1gb pomnilnika nam bo zadostovalo). Spodaj izberemo še "Use an existing virtual hard drive file" ter izberemo naš simpleArbiterDhcp in pritisnimo Create.</p>
+ </br>
+ <img style="width: 800px; height: 464px;" src="../images/10.png" alt="slika-10"></img>
+ <p>We run DHCP Server virtual machine and login using "root" ad username and "kaboom" as password.</br></br>
+ <p>At first, our machine has no assigned IP, since none was set! Let+s configure it in <b>/etc/network/interfaces</b>.</br>But which interface should we configure? Using <b>ifconfig -a</b> command, we see it's <b>eth0</b>interface.<br>
+ Again we select our IP address.</p>
+ <img style="width: 800px; height: 283px;" src="../images/11.png" alt="slika-11"></img>
+ <p>We save the configuration file. Our computer still has no IP address assigned to eth0, so using <b>ifdown eth0</b> and then <b>ifup eth0</b>we provide one.</p>
+ <img style="width: 800px; height: 25px;" src="../images/12.png" alt="slika-12"></img>
+ <p>Now let us use <b>ifconfig</b> command, to check whether there is an IP assigned to interface eth0</p>
+ <img style="width: 800px; height: 329px;" src="../images/13.png" alt="slika-13"></img>
+ <p>We got it! We install DHCP server using <b>apt-get install isc-dhcp-server</b></p>
+ <img style="width: 800px; height: 322px;" src="../images/14.png" alt="slika-14"></img>
+ <p>We see a bunch of errors. Why? Bacause, we have no internet access! <br>
+ We need to specify the Gateway for our inteface. Our Gateway bo seveda IP našega simpleArbiter navideznega računalnika.</br> To naredimo s pomočjo ukaza <b>route add default gw 192.168.251.1 eth0</b></p>
+ <img style="width: 800px; height: 43px;" src="../images/15.png" alt="slika-15"></img>
+ <p>Try pinging Google's DNS server at 8.8.8.8, to check if now have internet access.</br>
+ We do this using the <b>ping 8.8.8.8</b> command.</p>
+ <img style="width: 800px; height: 361px;" src="../images/16.png" alt="slika-16"></img>
+ <p>Google's DNS server is responding. Great! </br>
+ However, we still cannot run <b>apt-get install isc-dhcp-server</b></br>
+ Let's tempororly add another interface and set it to NAT, so we get internet access and install the DHCP server.</br></br>
+ We add a new interface by turning off the virtual computer, in VirtualBox we select our virtual machine and then select <b>Settings -> Network</b></br>
+ <b>Adapter 1</b> has already been set to Internal Network, we set <b>Adapter 2</b> to NAT</p>
+ <img style="width: 800px; height: 134px;" src="../images/17.png" alt="slika-17"></img>
+ <p>We run DHCP Server and in file<b>/etc/network/interfaces</b> at the end of the line add <b>iface eth1 inet dhcp</b>, then save the file and run <b>ifup eth1</b>.<br>
+ Now we have access to the internet and can install our DHCP server with <b>apt-get install isc-dhcp-server install</b> command</br>
+ <img style="width: 800px; height: 26px;" src="../images/18.png" alt="slika-18"></img></br>
+ <p>Let's see what's in<b>/var/log/syslog</b>, which is a file where our system information is stored in.</p>
+ <img style="width: 800px; height: 323px;" src="../images/19.png" alt="slika-19"></img></br>
+ <p>Looks like we need to set up a DHCP server and specify where it should listen! </br>
+ DHCP settings are stored in <b>/etc/dhcp/dhcpd.conf</b>. Let's set it! </br>
+ First let's comment out <b>option domain-name-servers</b> to avoid having errors.</p>
+ <img style="width: 800px; height: 26px;" src="../images/20.png" alt="slika-20"></img></br>
+ <p>Then we configure DHCP server, so it would serve IPs a a certain subnet. We add the following lines:</p>
+ <img style="width: 800px; height: 417px;" src="../images/21.png" alt="slika-21"></img>
+ <p><b>(subnet)</b> We set the subnet and the IP range, which the DHCP server should use, and which file it should serve.</p>Some PXEs are so unintelligent, that you should specify where they should get the files from and to do that you specify next-server </br>(IP from which it will be served from, in our case simpleArbiter), we also specify gateway, which, in our case is also simpleArbiter.</br></br>Ker bi radi, da v primeru zagona navideznega računalnika BootableClient B serviramo drugo datoteko, to naredimo tako da definiramo nek dodaten host na sledeč način:</br><b>(host special)</b> Pod <b>hardware ethernet</b> zapišemo MAC naslov našega BootableClient B katerega bo imel, dodelimo mu nek statičen ip naslov ter povemo še iz kje se naj datoteka <b>live-ISO</b> zažene.</p>
+ <p>We save the settings and kill terthe process with ubijemo named <b>dnsmasq</b>using<b>kilall dnsmasq</b>.</p>
+ <img style="width: 740px; height: 34px;" src="../images/22.png" alt="slika-22"></img>
+ <p>Sledi restart našega DHCP strežnika, da bo deloval z novimi nastavitvami, to naredimo z ukazom <b>service isc-dhcp-server restart</b></br>DHCP server is now ready! We supply BootableClientA and BootableClientB and test them!</p>
+
+
+ <h2 id="clientA">Postavitev <mark>BootableClient A</mark></h2>
+ <p>We open VirtualBox and select <b>New</b>, for the y
+<b>Name</b> field we specify
+BootableClient A and for the <b>Hard drive</b> we select <b>Do not add a
+virtual
+hard drive</b> (as we want diskless device), </br>and select Create.
+We want the computer to be on Internal network so vse select our
+<b>Bootable Client
+A</b> and select </br><b>Settings->Network</b> where we change Adapter
+1 to Internal Network.</p>
+ <img style="width: 800px; height: 678px;" src="../images/23.png" alt="slika-23"></img>
+ <p>We also wan our computer to boot through network, so
+under<b>Boot Order</b>tab select <b>Network</b>.</br>
+ We save the setting by clicking <b>OK</b></p>
+ <img style="width: 800px; height: 697px;" src="../images/24.png" alt="slika-24"></img>
+ <p>We run our BootableClient-a A and it get's it's
+IP(which is great), using the DHCP server and the simpleArbiter serves
+it exactly the file we specified. <b>A.0</b></p>
+ <img style="width: 800px; height: 494px;" src="../images/25.png" alt="slika-25"></img>
+
+
+
+ <h2 id="clientB">Setting up<mark>BootableClient
+B</mark></h2>
+ <p>Odpremo VirtualBox ter izberemo <b>New</b> in pod <b>Name</b> napišemo BootableClient B ter pod <b>Hard drive</b> izberemo <b>Do not add a virtual hard drive</b> (saj si želimo računalnik brez diska), </br>in pritisnemo na gump Create, da se nam ustvari navidezni računalnik. Želimo, da bo računalnik priklopljen na Internal network zato označimo naš <b>Bootable Client B</b> ter pritisnimo na </br><b>Settings->Network</b> in prvi Adapter 1 spremenimo na Internal Network.</br>
+ Poleg tega nastavimo še pod <b>MAC Address</b> takšen MAC naslov, kot ga imamo v nastavitvah DHCP strežnika (dhcpd.conf -> host special), saj želimo da bo ta naš računalnik izjema</br> in bo ob zagonu dobil drugo datoteko kot ostali in sicer <b>live-ISO</b></p>
+ <img style="width: 800px; height: 678px;" src="../images/26.png" alt="slika-26"></img>
+ <p>Želimo še, da se računalnik boot-a preko mreže, zato to nastavimo pod zavihkom <b>System</b></p> tako, da pod <b>Boot Order</b> obkljukamo samo <b>Network</b>.</br>
+ Nastavitve shranimo z pritiskom na gumb <b>OK</b></p>
+ <img style="width: 800px; height: 697px;" src="../images/27.png" alt="slika-27"></img>
+ <p>Poženemo našega BootableClient-a A in odličnoo, dobi ip naslov s pomočjo DHCP strežnika in simpleArbiter mu servira točno to datoteko katero si želimo <b>live-ISO</b></p>
+ <img style="width: 800px; height: 494px;" src="../images/28.png" alt="slika-28"></img>
+
+
+ </body>
+</html>
+
diff --git a/tasks/isc_dhcp_live_boot/howtos/en/indexEN.html.save b/tasks/isc_dhcp_live_boot/howtos/en/indexEN.html.save
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/en/indexEN.html.save
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/01.png b/tasks/isc_dhcp_live_boot/howtos/images/01.png
new file mode 100644
index 0000000..906135b
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/01.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/02.png b/tasks/isc_dhcp_live_boot/howtos/images/02.png
new file mode 100644
index 0000000..545f630
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/02.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/03.png b/tasks/isc_dhcp_live_boot/howtos/images/03.png
new file mode 100755
index 0000000..0b69590
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/03.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/04.png b/tasks/isc_dhcp_live_boot/howtos/images/04.png
new file mode 100755
index 0000000..ce4dc18
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/04.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/05.png b/tasks/isc_dhcp_live_boot/howtos/images/05.png
new file mode 100755
index 0000000..f343ec1
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/05.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/06.png b/tasks/isc_dhcp_live_boot/howtos/images/06.png
new file mode 100755
index 0000000..b4fe8e1
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/06.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/07.png b/tasks/isc_dhcp_live_boot/howtos/images/07.png
new file mode 100755
index 0000000..b6da6eb
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/07.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/08.png b/tasks/isc_dhcp_live_boot/howtos/images/08.png
new file mode 100755
index 0000000..333fd7d
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/08.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/09.png b/tasks/isc_dhcp_live_boot/howtos/images/09.png
new file mode 100755
index 0000000..c7cb8b8
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/09.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/10.png b/tasks/isc_dhcp_live_boot/howtos/images/10.png
new file mode 100755
index 0000000..c7f9225
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/10.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/11.png b/tasks/isc_dhcp_live_boot/howtos/images/11.png
new file mode 100755
index 0000000..e1192e9
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/11.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/12.png b/tasks/isc_dhcp_live_boot/howtos/images/12.png
new file mode 100755
index 0000000..295b3c7
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/12.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/13.png b/tasks/isc_dhcp_live_boot/howtos/images/13.png
new file mode 100755
index 0000000..8d3badc
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/13.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/14.png b/tasks/isc_dhcp_live_boot/howtos/images/14.png
new file mode 100755
index 0000000..3009f41
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/14.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/15.png b/tasks/isc_dhcp_live_boot/howtos/images/15.png
new file mode 100755
index 0000000..c4413e8
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/15.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/16.png b/tasks/isc_dhcp_live_boot/howtos/images/16.png
new file mode 100755
index 0000000..a4de5a8
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/16.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/17.png b/tasks/isc_dhcp_live_boot/howtos/images/17.png
new file mode 100755
index 0000000..0ab5c0f
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/17.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/18.png b/tasks/isc_dhcp_live_boot/howtos/images/18.png
new file mode 100755
index 0000000..4e1e17a
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/18.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/19.png b/tasks/isc_dhcp_live_boot/howtos/images/19.png
new file mode 100755
index 0000000..570f644
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/19.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/20.png b/tasks/isc_dhcp_live_boot/howtos/images/20.png
new file mode 100755
index 0000000..ea67ce0
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/20.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/21.png b/tasks/isc_dhcp_live_boot/howtos/images/21.png
new file mode 100755
index 0000000..428f92f
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/21.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/22.png b/tasks/isc_dhcp_live_boot/howtos/images/22.png
new file mode 100755
index 0000000..7119fff
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/22.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/23.png b/tasks/isc_dhcp_live_boot/howtos/images/23.png
new file mode 100755
index 0000000..68d0477
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/23.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/24.png b/tasks/isc_dhcp_live_boot/howtos/images/24.png
new file mode 100755
index 0000000..4ab2dd2
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/24.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/25.png b/tasks/isc_dhcp_live_boot/howtos/images/25.png
new file mode 100755
index 0000000..8823ac1
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/25.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/26.png b/tasks/isc_dhcp_live_boot/howtos/images/26.png
new file mode 100755
index 0000000..09eb081
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/26.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/27.png b/tasks/isc_dhcp_live_boot/howtos/images/27.png
new file mode 100755
index 0000000..9b867e1
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/27.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/images/28.png b/tasks/isc_dhcp_live_boot/howtos/images/28.png
new file mode 100755
index 0000000..5844b8a
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/images/28.png
Binary files differ
diff --git a/tasks/isc_dhcp_live_boot/howtos/si/index.html b/tasks/isc_dhcp_live_boot/howtos/si/index.html
new file mode 100644
index 0000000..d83b934
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/howtos/si/index.html
@@ -0,0 +1,147 @@
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>06 - preparation (isc_dhcp_live_boot)</title>
+ </head>
+
+ <body>
+ <h1 style="color:blue">06 - preparation (isc_dhcp_live_boot)</h1>
+ <h2>Kazalo</h2>
+ <ul>
+ <li><a href="#namen">Namen vaje</a></li>
+ <li><a href="#navidezniRacunalniki">Navidezni računalniki, ki so potrebni za izvedbo naloge</a></li>
+ <li><a href="#skicaPodomrezja">Skica našega podomrežja</a></li>
+ <li><a href="#simpleArbiterGW">Postavitev simpleArbiterGW</a></li>
+ <li><a href="#DHCP">Postavitev DHCP Server</a></li>
+ <li><a href="#clientA">Postavitev BootableClient A</a></li>
+ <li><a href="#clientB">Postavitev BootableClient B</a></li>
+ </ul>
+
+
+ <h2 id="namen">Namen vaje</h2>
+ <p>Kako narediti live boot z DHCP strežnikom.</p>
+
+ <h2 id="navidezniRacunalniki">Navidezni računalniki, ki so potrebni za izvedbo naloge</h2>
+ <p>Potrebujemo program VirtualBox ter naslednje 4 navidezne računalnike:
+ <ul>
+ <li><a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterGW.vdi">simpleArbiterGW</a></li>
+ <li><a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterDhcp.vdi">DHCP Server</a></li>
+ <li>Bootable Client A (računalnik brez diska)</li>
+ <li>Bootable Client B (računalnik brez diska)</li>
+ </ul>
+ </p>
+
+ <h2 id="skicaPodomrezja">Skica našega podomrežja</h2>
+ <img style="width: 800px; height: 610px;" src="../images/01.png" alt="slika-01"></img>
+ <p>Naš cilj je, da računalnik BootableClient A preko DHCP strežnika pridobil IP naslov ter se zažene z datoteko A, ki se nahaja na simpleArbiterGW,</br>če pa zaženemo računalnik BootableClient B pa si želimo, da ta preko DHCP strežnika pridobi IP naslov ter se zažene z nekim live ISO, ki se prav tako nahaja na simpleArbiterGW.
+ </p>
+
+ <h2 id="simpleArbiterGW">Postavitev <mark>simpleArbiterGW</mark></h2>
+ <p>Prenesemo <a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterGW.vdi">simpleArbiterGW.vdi</a> ter zaženemo VirtualBox. Ko je datoteka prenesena v VirtualBoxu izberemo New ter v polje Name vpišemo simpleArbiterGW.</br>Ustrezno nastavimo tudi Memory size (1gb pomnilnika nam bo zadostovalo). Spodaj izberemo še "Use an existing virtual hard drive file" ter izberemo naš simpleArbiterGW.vdi in pritisnimo Create.</p>
+ </br>
+ <img style="width: 800px; height: 464px;" src="../images/02.png" alt="slika-02"></img>
+ <p>Nato zaženemo virtualni računalnik simpleArbiterGW ter se z uporabniškim imenom "root" ter geslom "kaboom" vpišemo v naš sistem.</br></br>
+ Prvo računalnik od NAT-a, kateri je vgrajen v VirtualBox dobi nek naslov (v našem primeru 10.0.2.15).</br>(Da to preverimo uporabimo ukaz <b>ifconfig</b>) Preko tega IP naslova in vmesnika eth0 smo povezani v internet.<p>
+ <img style="width: 800px; height: 384px;" src="../images/03.png" alt="slika-03"></img>
+ <p>Mi pa si želimo 2 omrežna vmesnika na tem računalniku! Enega bi radi imeli na NAT (tega že imamo) drugega pa na Internal Network,</br>preko katerega bomo komunicirali z DHCP Strežnikom ter ostalimi računalniki, ki bodo v našem Internal Network-u.</br></br>
+ Nov omrežni vmesnik dodamo tako, da ugasnemo naš virtualni računalnik, ter v VirtualBoxu označimo naš virtualni računalnik in pritisnemo na <b>Settings -> Network</b></br>
+ <b>Adapter</b> 1 imamo že nastavljeno na NAT, <b>Adapter 2</b> pa nastavimo na Internal Network</p>
+ <img style="width: 800px; height: 137px;" src="../images/04.png" alt="slika-04"></img>
+ <p>Tako, zdaj imamo nastavljena 2 vmesnika!</br>V VirtualBoxu lahko definiramo več Internal Networkov (notranjih omrežij) a za naše potrebe bo to dovolj. Shranimo nastavitve ter ponovno poženimo naš simpleArbiterGW.</br></br>
+ Zdaj moramo oba omrežna vmesnika nastaviti tako, da bosta imela nek naslov. Uredimo datoteko <b>interfaces</b> v imeniku
+ <b>/etc/network</b>.</p>
+ <img style="width: 800px; height: 229px;" src="../images/05.png" alt="slika-05"></img>
+ <p>Za eth0 je poskrbel že DHCP strežnik, ki je vgrajen v VirtualBox (na eth0 je določil nek IP).</br>
+ Mi moramo nastaviti še drugi mrežni vmesnik. Kako se imenuje iz glave ne vemo zato s pomočjo ukaza <b>ifconfig -a</b> pogledamo.</p>
+ <img style="width: 800px; height: 117px;" src="../images/06.png" alt="slika-06"></img>
+ <p>Ugotovimo da je ime vmesnika eth1.
+ Zdaj bi rad na eth1 nastavil en IP naslov.</br>
+ Lahko bi nastavil z ifconfig, a ko rebootaš računalnik se nastavitve ne ohranijo. To nebi radi!</br>
+ Pojdimo raje skonfigurirat nastavitve v <b>/etc/network/interfaces</b></br></br>
+ Izmislimo si eno naključno lokalno omrežje oz naslov lokalnega omrežja ter nastavimo eth1.
+ </p>
+ <img style="width: 800px; height: 296px;" src="../images/07.png" alt="slika-07"></img>
+ <p>Shranimo konfiguracijsko datoteko. Moj računalnik še nima IP-ja na eth1 zato uporabim ukaz <b>ifup eth1</b></p>
+ <img style="width: 800px; height: 23px;" src="../images/08.png" alt="slika-08"></img></br>
+ <p>Sedaj uporabimo ukaz <b>ifconfig</b>, da vidimo če imamo slučajno ip na vmesniku eth1</p>
+ <img style="width: 800px; height: 389px;" src="../images/09.png" alt="slika-09"></img>
+ <p>Vidim, da ip imam. Super! Gremo postavit DHCP Server!</p>
+
+ <h2 id="DHCP">Postavitev <mark>DHCP Server</mark></h2>
+ <p>Prenesemo <a href="http://www.polz.si/media/uploads/kpov/virtualke/simpleArbiterDhcp.vdi">simpleArbiterDhcp.vdi</a> ter zaženemo VirtualBox. Ko je datoteka prenesena v VirtualBoxu izberemo New ter v polje Name vpišemo DHCP Server.</br>Ustrezno nastavimo tudi Memory size (1gb pomnilnika nam bo zadostovalo). Spodaj izberemo še "Use an existing virtual hard drive file" ter izberemo naš simpleArbiterDhcp in pritisnimo Create.<br>Ustrezno nastavimo tudi nastavitve mreže iz NAT na Internal Network</p>
+ </br>
+ <img style="width: 800px; height: 464px;" src="../images/10.png" alt="slika-10"></img>
+ <p>Nato zaženemo virtualni računalnik DHCP Server ter se z uporabniškim imenom "root" ter geslom "kaboom" vpišemo v naš sistem.</br></br>
+ <p>Sprva naš računalnik nima nobenega ip-ja saj mu ga nismo nastavili! Pojdimo skonfigurirat nastavitve v <b>/etc/network/interfaces</b>.</br>Ampak kateri vmesnik sploh konfiguriramo? Z ukazom <b>ifconfig -a</b> ugotovimo da je to <b>eth0</b>.<br>
+ Spet si izberemo nek svoj statičen ip naslov.</p>
+ <img style="width: 800px; height: 283px;" src="../images/11.png" alt="slika-11"></img>
+ <p>Shranimo konfiguracijsko datoteko. Moj računalnik še nima IP-ja na eth0 zato uporabim ukaz <b>ifdown eth0</b> ter nato še <b>ifup eth0</b></p>
+ <img style="width: 800px; height: 25px;" src="../images/12.png" alt="slika-12"></img>
+ <p>Sedaj uporabimo ukaz <b>ifconfig</b>, da vidimo če imamo slučajno ip na vmesniku eth0</p>
+ <img style="width: 800px; height: 329px;" src="../images/13.png" alt="slika-13"></img>
+ <p>Hura imamo! Namestimo naš DHCP strežnik z ukazom <b>apt-get install isc-dhcp-server</b></p>
+ <img style="width: 800px; height: 322px;" src="../images/14.png" alt="slika-14"></img>
+ <p>Vidimo, da dobimo cel kup napak. Ampak zakaj? Zato, ker nimamo dostopa do interneta! <br>
+ Vmesniku eth0 moramo seveda povedati Gateway. Naš Gateway bo seveda IP našega simpleArbiter navideznega računalnika.</br> To naredimo s pomočjo ukaza <b>route add default gw 192.168.251.1 eth0</b></p>
+ <img style="width: 800px; height: 43px;" src="../images/15.png" alt="slika-15"></img>
+ <p>Probajmo ping-ati Googlov DNS strežnik, da ugotovimo če imamo sedaj internet.</br>
+ To naredimo z ukazom <b>ping 8.8.8.8</b>.</p>
+ <img style="width: 800px; height: 361px;" src="../images/16.png" alt="slika-16"></img>
+ <p>Googlov DNS strežnik se odziva, super! </br>
+ Ampak <b>apt-get install isc-dhcp-server</b> še vedno ne moremo naložiti.</br>
+ Začasno dodajmo še en mrežni vmesnik ter ga nastavimo na NAT, nato bomo dobili dostop do interneta ter lahko namestimo naš DHCP strežnik.</br></br>
+ Nov omrežni vmesnik dodamo tako, da ugasnemo naš virtualni računalnik, ter v VirtualBoxu označimo naš virtualni računalnik in pritisnemo na <b>Settings -> Network</b></br>
+ <b>Adapter 1</b> imamo že nastavljeno na Internal Network, <b>Adapter 2</b> pa nastavimo na NAT</p>
+ <img style="width: 800px; height: 134px;" src="../images/17.png" alt="slika-17"></img>
+ <p>Zaženemo naš DHCP Server in v <b>/etc/network/interfaces</b> začasno na koncu dodamo vrstico <b>iface eth1 inet dhcp</b>,datoteko shranimo ter poženemo ukaz <b>ifup eth1</b>.<br>
+ Sedaj imamo dostop do interneta in lahko namestimo naš DHCP strežnik z ukazom <b>apt-get install isc-dhcp-server install</b></br>
+ <img style="width: 800px; height: 26px;" src="../images/18.png" alt="slika-18"></img></br>
+ <p>Poglejmo kaj je v <b>/var/log/syslog</b>, to je datoteka kamor se shranjujejo sporočila kaj se dogaja v našem sistemu</p>
+ <img style="width: 800px; height: 323px;" src="../images/19.png" alt="slika-19"></img></br>
+ <p>Očitno moramo nastaviti dhcp strežnik ter mu povedati tudi kam naj posluša! </br>
+ Za nastavitve DHCP strežnika imamo <b>/etc/dhcp/dhcpd.conf</b>. Nastavimo jo! </br>
+ Prvo zakomentiramo <b>option domain-name-servers</b> zaradi tega da nebo napak da jih ne najde.</p>
+ <img style="width: 800px; height: 26px;" src="../images/20.png" alt="slika-20"></img></br>
+ <p>Nato skonfiguriramo dhcp strežnik, da bo serviral ip-je na nekem podomrežju. Dodamo naslednje zapise:</p>
+ <img style="width: 800px; height: 417px;" src="../images/21.png" alt="slika-21"></img>
+ <p><b>(subnet)</b> Nastavimo podomrežje ter območje naslovov od koder naj jih DHCP strežnik dodeli, katero datoteko naj servira,</br> poleg tega so eni PXE tako neumni, da če jim ti serviraš filename nevejo iz katerega serverja ga dobim, zato napišem še next-server </br>(ip od koder serviram, v našem primeru simpleArbiter), nastavim tudi gateway kateri je v našem primeru tudi simpleArbiter.</br></br>Ker bi radi, da v primeru zagona navideznega računalnika BootableClient B serviramo drugo datoteko, to naredimo tako da definiramo nek dodaten host na sledeč način:</br><b>(host special)</b> Pod <b>hardware ethernet</b> zapišemo MAC naslov našega BootableClient B katerega bo imel, dodelimo mu nek statičen ip naslov ter povemo še iz kje se naj datoteka <b>live-ISO</b> zažene.</p>
+ <p>Spremembe shranimo, ter ubijemo proces z imenom <b>dnsmasq</b> z ukazom <b>kilall dnsmasq</b>.</p>
+ <img style="width: 740px; height: 34px;" src="../images/22.png" alt="slika-22"></img>
+ <p>Sledi restart našega DHCP strežnika, da bo deloval z novimi nastavitvami, to naredimo z ukazom <b>service isc-dhcp-server restart</b></br>DHCP Strežnik je pripravljen! Pripravimo BootableClientA ter BootableClientB ter testirajmo!</p>
+
+
+ <h2 id="clientA">Postavitev <mark>BootableClient A</mark></h2>
+ <p>Odpremo VirtualBox ter izberemo <b>New</b> in pod <b>Name</b> napišemo BootableClient A ter pod <b>Hard drive</b> izberemo <b>Do not add a virtual hard drive</b> (saj si želimo računalnik brez diska), </br>in pritisnemo na gump Create, da se nam ustvari navidezni računalnik. Želimo, da bo računalnik priklopljen na Internal network zato označimo naš <b>Bootable Client A</b> ter pritisnimo na </br><b>Settings->Network</b> in prvi Adapter 1 spremenimo na Internal Network.</p>
+ <img style="width: 800px; height: 678px;" src="../images/23.png" alt="slika-23"></img>
+ <p>Želimo še, da se računalnik boot-a preko mreže, zato to nastavimo pod zavihkom <b>System</b></p> tako, da pod <b>Boot Order</b> obkljukamo samo <b>Network</b>.</br>
+ Nastavitve shranimo z pritiskom na gumb <b>OK</b></p>
+ <img style="width: 800px; height: 697px;" src="../images/24.png" alt="slika-24"></img>
+ <p>Poženemo našega BootableClient-a A in odličnoo, dobi ip naslov s pomočjo DHCP strežnika in simpleArbiter mu servira točno to datoteko katero si želimo <b>A.0</b></p>
+ <img style="width: 800px; height: 494px;" src="../images/25.png" alt="slika-25"></img>
+
+
+
+ <h2 id="clientB">Postavitev <mark>BootableClient B</mark></h2>
+ <p>Odpremo VirtualBox ter izberemo <b>New</b> in pod <b>Name</b> napišemo BootableClient B ter pod <b>Hard drive</b> izberemo <b>Do not add a virtual hard drive</b> (saj si želimo računalnik brez diska), </br>in pritisnemo na gump Create, da se nam ustvari navidezni računalnik. Želimo, da bo računalnik priklopljen na Internal network zato označimo naš <b>Bootable Client B</b> ter pritisnimo na </br><b>Settings->Network</b> in prvi Adapter 1 spremenimo na Internal Network.</br>
+ Poleg tega nastavimo še pod <b>MAC Address</b> takšen MAC naslov, kot ga imamo v nastavitvah DHCP strežnika (dhcpd.conf -> host special), saj želimo da bo ta naš računalnik izjema</br> in bo ob zagonu dobil drugo datoteko kot ostali in sicer <b>live-ISO</b></p>
+ <img style="width: 800px; height: 678px;" src="../images/26.png" alt="slika-26"></img>
+ <p>Želimo še, da se računalnik boot-a preko mreže, zato to nastavimo pod zavihkom <b>System</b></p> tako, da pod <b>Boot Order</b> obkljukamo samo <b>Network</b>.</br>
+ Nastavitve shranimo z pritiskom na gumb <b>OK</b></p>
+ <img style="width: 800px; height: 697px;" src="../images/27.png" alt="slika-27"></img>
+ <p>Poženemo našega BootableClient-a A in odličnoo, dobi ip naslov s pomočjo DHCP strežnika in simpleArbiter mu servira točno to datoteko katero si želimo <b>live-ISO</b></p>
+ <img style="width: 800px; height: 494px;" src="../images/28.png" alt="slika-28"></img>
+<h2 id="tftpInPxe">Postavitev <mark>TFTP strežnika in zagonskih datotek</mark></h2>
+
+<p>Na SimpleArbiter namestimo TFTP strežnik z ukazom <b>apt-get install tftpd-hpa</b> in spremenimo IP v <b>"/etc/default/tftpd-hpa"</b> pod TFTP_ADDRES na "192.168.251.1".
+<br>Nato z ukazom <b>apt-get install syslinux</b> namestimo syslinux in skopiramo zagonsko datoteko iz "/usr/lib/syslinux/pxelinux.0" na "/srv/tftp/A.0.<br> Namestimo še NFS server z ukazom "apt-get install nfs-kernel-server" in v "/etc/exports" dodamo lokacijo mape, kjer se nahaja naša zagonska datoteka A.0, ter omogočimo branje ("/srv/tftp * (ro)").
+<br>V imeniku /srv/tftp ustvarimo mapo "pxelinux.cfg" in v njej ustvarimo datoteko z imenom default. Vanjo vpišemo :
+<br>DEFAULT vesamenu.c32
+<br>PROMPT 0
+<br>MENU TITLE isc-dhcp-live
+<br>LABEL iso
+<br> menu label Run
+<br> kernel vmlinuz
+<br> APPEND boot=casper netboot=nfs nfsroot=192.168.251.1:/srv/tftp/boot/ initrd=initrd.gz</p>
+ </body>
+</html>
+
diff --git a/tasks/isc_dhcp_live_boot/task.py b/tasks/isc_dhcp_live_boot/task.py
new file mode 100644
index 0000000..c1adc47
--- /dev/null
+++ b/tasks/isc_dhcp_live_boot/task.py
@@ -0,0 +1,222 @@
+# TODO: dokoncaj!
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si': '''\
+<p>
+Postavi štiri navidezne računalnike: <em>simpleArbiter</em>, <em>DHCP_server</em>, <em>BootableClientA</em> in <em>BootableClientB</em>.
+
+<p>
+Na <em>DHCP_server</em> postavi strežnik DHCP s pomočjo ISC dhcp 3 na naslovu <code>{{IP_DHCP}}</code>. <em>SimpleArbiter</em> naj dobi <code>{{IP_GW}}</code>. <em>DHCP_server</em> naj ga uporabi kot privzeti prehod (angl. <em lang="en">gateway</em>).
+
+<p>
+Če se zaganja <em>BootableClientB</em>, naj se sistem zažene v datoteko z imenom <code>{{BOOT_FNAME}}</code>. Če se zaganja katerikoli drug, naj se sistem zažene z živega USB, ki ga predstavlja slika diska <code>bootable_usb</code>, ime datoteke z zagonskim nalagalnikom pa naj bo kakršno koli razen <code>{{BOOT_FNAME}}</code>.
+
+<p>
+Živi USB priklopite na na <em>DHCP_server</em> in z njega poberite datoteke, potrebne za zagon. Datoteke z nastavitvami za PXELinux, ki jih najdete na živem USB, <em>morajo</em> biti dostopne na korenskem imeniku strežnika TFTP.
+
+<p>
+Tako <em>BootableClientA</em> kot <em>BootableClientB</em> naj bosta brez diskov.
+''',
+ 'en': '''\
+<p>
+Set up four virtual machines: <em>simpleArbiter</em>, <em>DHCP_server</em>, <em>BootableClientA</em> and <em>BootableClientB</em>.
+
+<p>
+On <em>DHCP_server</em>, set up a DHCP server using ISC dhcp 3. Set the IP address of this server to <code>{{IP_DHCP}}</code>. If <em>SimpleArbiter</em> requests an IP, have the DHCP server serve it <code>{{IP_GW}}</code>. <em>DHCP_server</em> should use <em>SimpleArbiter</em> as the gateway.
+
+<p>
+If <em>BootableClientB</em> tries to boot over the network, have the DHCP server tell it to boot from the file <code>{{BOOT_FNAME}}</code>. If any other system tries to boot over the network, have it boot from a live USB drive represented by the disk image <code>bootable_usb</code> and have the bootloader filename be different from <code>{{BOOT_FNAME}}</code>.
+
+<p>
+Connect the live USB to DHCP_server and copy the files neccessarry for it to boot. The PXELinux configuration files must be the same as the ones found on the live USB and <em>must</em> be accessible on the TFTP server root.
+
+<p>
+Both <em>BootableCLientA</em> and <em>BootableClientB</em> should be diskless.
+''',
+}
+
+computers = {
+ 'DHCPServer': {
+ 'disks': [
+ { 'name': 'student-DHCPServer',
+ },
+ { 'name': 'bootable_usb',
+ 'options':{'readonly': False},
+ 'parts': [ {'dev': 'sdb1', 'path':'/mnt'} ],
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'BootableClientA': {
+ 'disks': [
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'BootableClientB': {
+ 'disks': [
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterGW',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_DHCP': {'descriptions': {'si': 'IP DHCP streznika'}, 'w': False, 'public': True, 'type':'IP', 'generated': True},
+ 'IP_GW': {'descriptions': {'si': 'IP SimpleArbiterja'}, 'w': False, 'public': True, 'type':'IP', 'generated': True},
+ 'MAC_BOOT': {'descriptions': {'si': 'MAC racunalnika, ki se zazene z ISO'}, 'w': True, 'public': True, 'type':'MAC', 'generated': False},
+ # 'IP_BOOT': {'descriptions': {'si': 'IP racunalnika, ki se zazene z ISO'}, 'w': True, 'public': True, 'type':'IP', 'generated': False},
+ 'TFTP_STRING': {'descriptions': {'si': 'vsebina'}, 'w': False, 'public': False, 'type':'short', 'generated': True},
+ 'BOOT_FNAME': {'descriptions': {'si': 'Ime datoteke'}, 'w': False, 'public': True, 'type': 'filename', 'generated': True},
+}
+
+def task(IP_DHCP, IP_GW, MAC_BOOT, BOOT_FNAME):
+ # check the IP
+ # TODO (polz): Do not use tabs instead of spaces!
+ import pexpect
+ import re
+ import tftpy
+ import io
+ import time
+ results={}
+ # TODO (polz): Please use pexpect instead of os.system, it's much nicer.
+ # Also, test your functions. This function was obviously never run.
+ #
+ # check whether the fname served by the dhcp server is
+ # correct
+ # you should check the DHCP response from the server.
+ # You can use dhcpdump to get some packets, dhcping to create a
+ # DHCP Request. You may also use any other tool.
+ # If you choose to use dhcping, do not forget to set the hw address
+ # and ip arguments. You can simply feed it MAC_BOOT and IP_BOOT.
+ # dhcping -h MAC_BOOT -c IP_BOOT -V -r
+ # could work (but you should test it)
+ ip_str = pexpect.run('ip addr show')
+ eth_re_str = r"ether (([0-9a-f]{{2}}:){{5}}[0-9a-f]{{2}})(.*)\r\n(.*){}(.*)\s(\w*)\r\n"
+ ip_re = re.search(eth_re_str.format(IP_GW), ip_str)
+ mac_SA = ip_re.group(1)
+ eth_dev_SA = ip_re.group(6)
+ dhcpdump = pexpect.spawn("sudo dhcpdump -i {}".format(eth_dev_SA))
+ time.sleep(2)
+ results['dhcping_other'] = pexpect.run('sudo dhcping -s {} -h {} -c {}'.format(
+ IP_DHCP, MAC_BOOT, IP_GW))
+ dhcpdump.expect('---------------------------------------------------------------------------')
+ results['dhcpdump_other_req'] = dhcpdump.before
+ dhcpdump.expect('---------------------------------------------------------------------------')
+ results['dhcpdump_other_reply'] = dhcpdump.before
+ dhcpdump.expect('---------------------------------------------------------------------------')
+ results['dhcpdump_other_release'] = dhcpdump.before
+ results['dhcping_SA'] = pexpect.run('sudo dhcping -s {} -h {} -c {}'.format(
+ IP_DHCP, mac_SA, IP_GW))
+ dhcpdump.expect('---------------------------------------------------------------------------')
+ results['dhcpdump_SA_req'] = dhcpdump.before
+ dhcpdump.expect('---------------------------------------------------------------------------')
+ results['dhcpdump_SA_reply'] = dhcpdump.before
+ dhcpdump.expect('---------------------------------------------------------------------------')
+ results['dhcpdump_SA_release'] = dhcpdump.before
+ dhcpdump.sendintr()
+ tftp_client = pexpect.spawn('tftp {}'.format(IP_DHCP))
+ tftp_client.expect(r'tftp>')
+ tftp_client.sendline('get pxelinux.cfg/default /dev/stdout')
+ tftp_client.expect(r'tftp>')
+ results['tftp_string'] = tftp_client.before
+ # check whether the fname served by the dhcp server is correct
+ # connect to the service in the special ISO
+ # check the MAC of the server on IP_BOOT
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ net = kpov_util.IPv4_subnet_gen(r, '10.64.0.0/10', 24)
+ params['IP_DHCP'], params['IP_GW'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['BOOT_FNAME'] = kpov_util.fname_gen(r)
+ params['TFTP_STRING'] = kpov_util.alnum_gen(r, 45)
+ return params
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+ #TO FINISH SCORING WE REQUIRE DICT KEYS AND FUNCTIONS gen_params AND task TO BE FINISHED
+ #POINTS FOR EACH TASK MAY BE ADJUSTED IN THE FUTURE
+ if results['dhcping_other'].find(params['IP_DHCP']) >= 0:
+ score += 1
+ else:
+ hints += ["DHCP wrong"]
+ if results['dhcping_SA'].find(params['IP_DHCP']) >= 0:
+ score += 1
+ else:
+ hints += ["DHCP wrong"]
+ p = re.search(r"FNAME:(.*)\.\r",
+ results['dhcpdump_other_reply'])
+ if p is not None:
+ other_fname = p.group(1).strip()
+ else:
+ other_fname = ''
+ if other_fname == params['BOOT_FNAME']:
+ score += 3
+ else:
+ hints += ["special fname wrong:" + other_fname]
+ p = re.search(r"FNAME:(.*)\.\r",
+ results['dhcpdump_SA_reply'])
+ if p is not None:
+ sa_fname = p.group(1).strip()
+ else:
+ sa_fname = ''
+ if sa_fname != params['BOOT_FNAME']:
+ score += 3
+ else:
+ hints += ["fname wrong:" + sa_fname]
+ try:
+ special_tftp = "# " + params['TFTP_STRING']
+ tftp_end = results['tftp_string'].split('\r\r\n')[-1]
+ assert tftp_end[:len(special_tftp)] == special_tftp
+ score += 2
+ except:
+ hints += ["tftp wrong"]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ d = templates['student-DHCPServer']
+ s = """# {}""".format(task_params['TFTP_STRING'])
+ d = templates['bootable_usb']
+ d.write_append('/mnt/syslinux.cfg', s)
+ d = templates['simpleArbiterGW']
+ s = """auto lo
+iface lo inet loopback
+
+auto ens3
+iface ens3 inet dhcp
+
+auto enp0s3
+iface enp0s3 inet dhcp
+
+auto ens4
+iface ens4 inet static
+ address {IP_GW}
+ netmask 255.192.0.0
+
+auto enp0s8
+iface enp0s8 inet static
+ address {IP_GW}
+ netmask 255.192.0.0
+""".format(IP_GW = task_params['IP_GW'])
+ d.write("/etc/network/interfaces", s)
+ write_default_config(templates['simpleArbiterGW'], global_params)
diff --git a/tasks/ldap_import/task.py b/tasks/ldap_import/task.py
new file mode 100644
index 0000000..f8fdd60
--- /dev/null
+++ b/tasks/ldap_import/task.py
@@ -0,0 +1,106 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Ustvari dva navidezna računalnika - SimpleArbiter z diskom simpleArbiterDhcp ter LDAPServer.
+Na LDAPServer namesti strežnik LDAP. Na SimpleArbiter preberi ime domene DOMENA,
+uporabniško ime BIND_DN ter geslo BIND_PASS. Poskrbi, da se bo lahko klient s simpleArbiterDhcp povezal na LDAP strežnik na LDAPServer.
+V primeru, da se klient poveže kot BIND_DN z geslom BIND_PASS, naj strežnik omogoči branje vseh podatkov za objekte v
+DC=DOMENA,DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si. Nato na LDAP strežniku poišči datoteko /home/test/users.txt. Vsaka vrstica
+v datoteki vsebuje uporabniško ime, ime ter priimek, ločene s tabulatorji. V bazi LDAP
+pod DC=DOMENA,DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si za vsako vrstico v users.txt ustvari svojega uporabnika.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions': {'si': 'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
+
diff --git a/tasks/ldap_search/howtos/en/Pic1.jpg b/tasks/ldap_search/howtos/en/Pic1.jpg
new file mode 100644
index 0000000..fecb706
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic1.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic2.1.jpg b/tasks/ldap_search/howtos/en/Pic2.1.jpg
new file mode 100644
index 0000000..085f1cc
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic2.1.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic2.2.jpg b/tasks/ldap_search/howtos/en/Pic2.2.jpg
new file mode 100644
index 0000000..cb9975c
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic2.2.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic2.3.jpg b/tasks/ldap_search/howtos/en/Pic2.3.jpg
new file mode 100644
index 0000000..1069e1a
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic2.3.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.1.jpg b/tasks/ldap_search/howtos/en/Pic3.1.jpg
new file mode 100644
index 0000000..0c00ddd
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.1.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.2.jpg b/tasks/ldap_search/howtos/en/Pic3.2.jpg
new file mode 100644
index 0000000..d488e43
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.2.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.3.jpg b/tasks/ldap_search/howtos/en/Pic3.3.jpg
new file mode 100644
index 0000000..2ea916c
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.3.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.4.jpg b/tasks/ldap_search/howtos/en/Pic3.4.jpg
new file mode 100644
index 0000000..24db305
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.4.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.5.jpg b/tasks/ldap_search/howtos/en/Pic3.5.jpg
new file mode 100644
index 0000000..d2ff304
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.5.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.6.jpg b/tasks/ldap_search/howtos/en/Pic3.6.jpg
new file mode 100644
index 0000000..0ab07d0
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.6.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.7.jpg b/tasks/ldap_search/howtos/en/Pic3.7.jpg
new file mode 100644
index 0000000..44ca494
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.7.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic3.8.jpg b/tasks/ldap_search/howtos/en/Pic3.8.jpg
new file mode 100644
index 0000000..855353b
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic3.8.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic4.jpg b/tasks/ldap_search/howtos/en/Pic4.jpg
new file mode 100644
index 0000000..4aab71d
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic4.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic5.jpg b/tasks/ldap_search/howtos/en/Pic5.jpg
new file mode 100644
index 0000000..07a60de
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic5.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic6.jpg b/tasks/ldap_search/howtos/en/Pic6.jpg
new file mode 100644
index 0000000..48c6606
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic6.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic7.jpg b/tasks/ldap_search/howtos/en/Pic7.jpg
new file mode 100644
index 0000000..58b8bdf
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic7.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/Pic8.jpg b/tasks/ldap_search/howtos/en/Pic8.jpg
new file mode 100644
index 0000000..c9d053e
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/Pic8.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/en/index.html b/tasks/ldap_search/howtos/en/index.html
new file mode 100644
index 0000000..31bb1e9
--- /dev/null
+++ b/tasks/ldap_search/howtos/en/index.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>ldap_search</title>
+ <meta charset="utf-8">
+</head>
+<body>
+</body>
+<h1>ldap_search</h1>
+<h2>Purpose of the exercise</h2>
+<p>How to setup a LDAP Server, to add entries to a LDAP Server, and to change users' rights to be able to add entries and change the attributes of entries.</p>
+
+<h2>How To</h2>
+
+<ol>
+ <li>Create two virtual machines, <b>SimpleArbiterDhcpGWLDAP</b>(simpleArbiterDhcpGWLDAP.vdi) and <b>LDAPServer</b>(student-LDAPServer.vdi).
+ <br><img src="../images/Pic1.jpg" alt="No img" width=600 height=400></li>
+ <br>
+ <li>Change the network settings to both virtual machines. <b>SimpleArbiterDhcpGWLDAP</b>: Adapter 1 is set to "NAT" for internet access and
+ adapter 2 to "internal network" for local network. <b>LDAPServer</b>: Adapter 1 set to "internal network" sot that it is in the same internal network as SimpleArbiterDhcpGWLDAP.
+ <br><img src="../images/Pic2.1.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic2.2.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic2.3.jpg" alt="No img" width=600 height=400></li>
+ <br>
+ <li>In <b>SimpleArbiterDhcpGWLDAP</b> log in as user "tester", in <b>LDAPServer</b> log in as user "root", run the command <b>"apt-get update"</b> to update the list of packages and
+ open up another terminal by pressing <b>"ALT+F2"</b> and log in as user "student".</li>
+ <br>
+ <li>In <b>LDAPServer</b> run the command <b>"apt-get install slapd ldap-utils"</b> to install these packages which are the LDAP server and tools to access and manage the LDAP server.
+ <br>During the LDAP server installation you'll have to provide the password for the user "admin", the administrator of the server and confirm the password chosen.</li>
+ <br>
+ <li>Configure the LDAP server by choosing the appropriate domain name and other configuration parameters. Execute the commmand <b>"dpkg-reconfigure slapd"</b>.
+ <br><img src="../images/Pic3.1.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.2.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.3.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.4.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.5.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.6.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.7.jpg" alt="No img" width=600 height=400>
+ <br><img src="../images/Pic3.8.jpg" alt="No img" width=600 height=400>
+ <br>a) If you will configure the <b>"slapd"</b> again don't forget to remove the old database <b>"rm -rf /var/backups/unknown-2.4.44+dfsg-2.ldapdb"</b>.</li>
+ <br>
+ <li>Now that the LDAP server is configured for use, try to open a third console and log in as user "student" and execute the command <b>"ldapsearch -D cn=admin,dc=ceres-20,dc=kpov,
+ dc=lusy,dc=fri,dc=uni-lj,dc=si -W -b dc=ceres-20,dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si"</b>, which will show the entries in the server.
+ <br>Because you will be using a lot the domain name to access the LDAP server you can set the environment variable "D", which will allow for quicker typing of commands.
+ <br><b>"export D=dc=ceres-20,dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si"</b>
+ <br><b>"ldapsearch -D cn=admin,$D -wvaje -b $D"</b></li>
+ <br>
+ <li>Create the file(LDIF format) "users.ldif" which will contain the objects(users) that we want to add to the LDAP server database.
+ <br><img src="../images/Pic4.jpg" alt="No img" width=600 height=400>
+ <br>Execute the following command to add users to the LDAP server:
+ <br><b>"ldapadd -D cn=admin,$D -wvaje -f users.ldif"</b>
+ <br>Add password to the users added to the LDAP server:
+ <br><b>"ldappasswd -D cn=admin,$D -wvaje -sj2531e cn=ninavidmar,ou=users,$D"</b>
+ <br><b>"ldappasswd -D cn=admin,$D -wvaje -scTyRM0 cn=natalijaribnikar39,ou=users,$D"</b>
+ <br>Execute command <b>"ldapsearch -D cn=natalijaribnikar39,ou=users,$D -wcTyRM0 -b $D"</b> to bind to the LDAP server with the newly added user <b>"natalijaribnikar39"</b> and to see the entries currently in the LDAP server.
+ <br><img src="../images/Pic5.jpg" alt="No img" width=600 height=400></li>
+ <br>
+ <li>In order to change the users' rights settings, which allows a user to add entries to the directory and change values of attributes of entries in the directory you need to create an additional file acl.ldif:
+ <br>To see which backend database is used and other settings related to the users' rights execute command <b>"ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config"</b> as root user in the system, which does not need the user authentication to the LDAP server.
+ <br><img src="../images/Pic6.jpg" alt="No img" width=600 height=400>
+ <br>The settings in the acl.ldif file:
+ <br><img src="../images/Pic7.jpg" alt="No img" width=600 height=400>
+ <br>Now to change users' rights run the command <b>"ldapmodify -Y EXTERNAL -H ldapi:/// -f acl.ldif"</b> as user "root" in the system.</li>
+ <br>
+ <li>The user <b>"natalijaribnikar39"</b> has the right to add or change objects in the LDAP server.
+ <br>Now try to bind to the LDAP server using <b>"natalijaribnikar39"</b> user's credentials and add a new user to the server directory.
+ <br><b>"ldapadd -D cn=natalijaribnikar39,ou=users,$D -wcTyRM0 -f newuser.ldif"</b></li>
+ <br>
+ <li>Now to test your result go to the <b>SimpleArbiterDhcpGWLDAP</b> virtual machine and run <b>"./test_task.py"</b> to run the test and see your score.
+ <br><img src="../images/Pic8.jpg" alt="No img" width=600 height=400></li>
+
+</ol>
+
+</html>
diff --git a/tasks/ldap_search/howtos/images/1.png b/tasks/ldap_search/howtos/images/1.png
new file mode 100644
index 0000000..f4edca8
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/1.png
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/2.png b/tasks/ldap_search/howtos/images/2.png
new file mode 100644
index 0000000..4d4ebb5
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/2.png
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic1.jpg b/tasks/ldap_search/howtos/images/Pic1.jpg
new file mode 100644
index 0000000..fecb706
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic1.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic2.1.jpg b/tasks/ldap_search/howtos/images/Pic2.1.jpg
new file mode 100644
index 0000000..085f1cc
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic2.1.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic2.2.jpg b/tasks/ldap_search/howtos/images/Pic2.2.jpg
new file mode 100644
index 0000000..cb9975c
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic2.2.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic2.3.jpg b/tasks/ldap_search/howtos/images/Pic2.3.jpg
new file mode 100644
index 0000000..1069e1a
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic2.3.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.1.jpg b/tasks/ldap_search/howtos/images/Pic3.1.jpg
new file mode 100644
index 0000000..0c00ddd
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.1.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.2.jpg b/tasks/ldap_search/howtos/images/Pic3.2.jpg
new file mode 100644
index 0000000..d488e43
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.2.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.3.jpg b/tasks/ldap_search/howtos/images/Pic3.3.jpg
new file mode 100644
index 0000000..2ea916c
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.3.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.4.jpg b/tasks/ldap_search/howtos/images/Pic3.4.jpg
new file mode 100644
index 0000000..24db305
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.4.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.5.jpg b/tasks/ldap_search/howtos/images/Pic3.5.jpg
new file mode 100644
index 0000000..d2ff304
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.5.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.6.jpg b/tasks/ldap_search/howtos/images/Pic3.6.jpg
new file mode 100644
index 0000000..0ab07d0
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.6.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.7.jpg b/tasks/ldap_search/howtos/images/Pic3.7.jpg
new file mode 100644
index 0000000..44ca494
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.7.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic3.8.jpg b/tasks/ldap_search/howtos/images/Pic3.8.jpg
new file mode 100644
index 0000000..855353b
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic3.8.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic4.jpg b/tasks/ldap_search/howtos/images/Pic4.jpg
new file mode 100644
index 0000000..4aab71d
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic4.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic5.jpg b/tasks/ldap_search/howtos/images/Pic5.jpg
new file mode 100644
index 0000000..07a60de
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic5.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic6.jpg b/tasks/ldap_search/howtos/images/Pic6.jpg
new file mode 100644
index 0000000..48c6606
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic6.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic7.jpg b/tasks/ldap_search/howtos/images/Pic7.jpg
new file mode 100644
index 0000000..58b8bdf
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic7.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/images/Pic8.jpg b/tasks/ldap_search/howtos/images/Pic8.jpg
new file mode 100644
index 0000000..c9d053e
--- /dev/null
+++ b/tasks/ldap_search/howtos/images/Pic8.jpg
Binary files differ
diff --git a/tasks/ldap_search/howtos/si/index.html b/tasks/ldap_search/howtos/si/index.html
new file mode 100644
index 0000000..7370099
--- /dev/null
+++ b/tasks/ldap_search/howtos/si/index.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+<body>
+<h1>Naloga: ldap search</h1>
+<p>
+<h2>Povzetek naloge</h2>
+Ustvari 2 virtualna sistema SimpleArbiterDhcp ter LDAPServer ter se s SimpleArbiterDhcp povezi na LDAP server na drugem virtualnem sistemu. Ustvari uporabnika.
+</p>
+<p>
+<h2>Navodila</h2>
+ 1. Prenesite disk SimpleArbiterDhcp preko imenika s diski virtualnih naprav.
+ 2. V Virtualbox ustvarite nov racunalnik SimpleArbiterDhcp in uporabite prenešen disk.(Slika 1)
+ 3. Prav tako naredi drugi virtualni sistem poimenovan LDAPServer.
+ 4. Na oba sistema se prijavi kot uporabnik "root" z geslom "kaboom".
+ 5. Na sistemi LDAPServer namesti LDAP z ukazom 'apt-get install ldap-utils.(Slika 2)
+ 6. Po prenosu vkljucite LDAP server.
+ 7. S sistema SimpleArbiterDhcp se povezi na LDAP streznik na sistemu LDAPServer.
+ 8. Ustvari uporabnika na LDAP serverju.
+</p>
+</body>
+</html>
diff --git a/tasks/ldap_search/task.py b/tasks/ldap_search/task.py
new file mode 100644
index 0000000..29117db
--- /dev/null
+++ b/tasks/ldap_search/task.py
@@ -0,0 +1,210 @@
+# kpov_util should be imported by add_assignment.py
+
+# Poveži se na strežnik LDAP prek spletnega vmesnika. Ustvari uporabnika z danim imenom in geslom.
+# Napiši skripto, ki izpiše podatke o tem uporabniku z ldapsearch.
+
+# TODO: finish this!
+instructions = {
+ 'si': '''\
+<p>
+Ustvari dva navidezna računalnika: <em>SimpleArbiter</em> in <em>LDAPServer</em>.
+
+<p>
+Na <em>LDAPServer</em> namesti strežnik LDAP. Strežnik naj skrbi za domeno
+
+<pre><code>DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+V imeniku ustvari uporabnika
+
+<pre><code>CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+z geslom <code>{{LDAP_PASSWORD}}</code> in uporabnika
+
+<pre><code>CN={{BIND_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+z geslom <code>{{BIND_PASSWORD}}</code>.
+
+<p>
+Poskrbi, da se bo lahko klient s <em>SimpleArbiter</em> povezal na LDAP strežnik na <em>LDAPServer</em>.
+V primeru, da se klient poveže kot <code>{{BIND_USERNAME}}</code> z geslom <code>{{BIND_PASSWORD}}</code>,
+naj strežnik omogoči spreminjanje podatkov za objekt
+
+<pre><code>CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+ter ustvarjanje novih objektov v
+
+<pre><code>DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
+
+CN = Common Name
+O = Organization
+OU = Organizational Unit
+DC = Domain Component
+</code></pre>
+''',
+ 'en': '''\
+<p>
+Create two virtual machines: <em>SimpleArbiter</em> and <em>LDAPServer</em>.
+
+<p>
+Set up an LDAP server on <em>LDAPServer</em>. Make it responsible for
+
+<pre><code>DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+Create a user
+
+<pre><code>CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+with the password <code>{{LDAP_PASSWORD}}</code>, and a user
+
+<pre><code>CN={{BIND_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+with the password <code>{{LDAP_PASSWORD}}</code> .
+
+<p>
+Make sure that a client from <em>SimpleArbiter</em> can connect to the LDAP server on <em>LDAPServer</em>. If the client identifies themself as <code>{{BIND_USERNAME}}</code> with the password <code>{{BIND_PASSWORD}}</code>, allow it to change data for the object
+
+<pre><code>CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si</code></pre>
+
+<p>
+and to create objects in
+
+<pre><code>DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
+
+CN = Common Name
+O = Organization
+OU = Organizational Unit
+DC = Domain Component
+</code></pre>
+''',
+}
+
+computers = {
+ 'LDAPServer': {
+ 'disks': [
+ { 'name': 'student-LDAPServer',
+ },
+ #{ 'name': 'CDROM',
+ # 'options':{'readonly': True},
+ # 'parts': [],# no parts, no mounting.
+ #}
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGWLDAP',
+ # 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 = {
+ 'LDAP_IP': {'descriptions': {'si': 'IP strežnika', 'en': 'Server IP'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'DOMAIN': {'descriptions': {'si': 'Domena (poddomena kpov.lusy.fri.uni-lj.si)', 'en': 'Domain (subdomain of kpov.lusy.fri.uni-lj.si)'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
+ 'LDAP_USERNAME': {'descriptions': {'si': 'Uporabniško ime v LDAP', 'en': 'Username in LDAP'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
+ 'LDAP_PASSWORD': {'descriptions': {'si': 'Geslo v LDAP', 'en': 'LDAP password'}, 'w': False, 'public':True, 'type': 'password', 'generated': True},
+ 'BIND_USERNAME': {'descriptions': {'si': 'Uporabniško ime za dostop do LDAP (bind)', 'en': 'Bind username in LDAP'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
+ 'BIND_PASSWORD': {'descriptions': {'si': 'Geslo za dostop do LDAP (bind)', 'en': 'Bind password in LDAP'}, 'w': False, 'public':True, 'type': 'password', 'generated': True},
+}
+
+def task(LDAP_IP, DOMAIN, LDAP_USERNAME, LDAP_PASSWORD, BIND_USERNAME, BIND_PASSWORD):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ FULLDOMAIN = "dc={DOMAIN},dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si".format(
+ **locals())
+ BIND_DN = "cn={BIND_USERNAME},ou=Users,{FULLDOMAIN}".format(**locals())
+ s = "ldapsearch -D {BIND_DN} -b {FULLDOMAIN} -w {BIND_PASSWORD}\
+ -h {LDAP_IP}".format(
+ **locals())
+ results['ldapsearch_before'] = pexpect.run(s)
+ s = "ldapmodify -D {BIND_DN} -w {BIND_PASSWORD} -h {LDAP_IP}".format(
+ **locals())
+ modify = pexpect.spawn(s)
+ FORTUNE = kpov_util.hostname_gen(random.Random(str(LDAP_USERNAME)))
+ results['fortune'] = FORTUNE
+ s1 = """
+dn: cn={LDAP_USERNAME},ou=Users,{FULLDOMAIN}
+changetype: modify
+replace: description
+description: {FORTUNE}
+""".format(**locals())
+ modify.write(s1)
+ modify.sendeof()
+ modify.expect(pexpect.EOF)
+ results['modify'] = modify.before
+ s = "ldapsearch -D {BIND_DN} -b {FULLDOMAIN} -w {BIND_PASSWORD}\
+ -h {LDAP_IP}".format(**locals())
+ results['ldapsearch_after'] = pexpect.run(s)
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ params['DOMAIN'] = kpov_util.hostname_gen(r)
+ params['LDAP_USERNAME'] = kpov_util.username_gen(r)
+ params['LDAP_PASSWORD'] = kpov_util.alnum_gen(r, 6)
+ params['BIND_USERNAME'] = kpov_util.username_gen(r)
+ params['BIND_PASSWORD'] = kpov_util.alnum_gen(r, 6)
+ return params
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+ s = """.*dn: dc={DOMAIN},dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si\r[^#]*
+objectClass: top\r
+objectClass: dcObject\r
+objectClass: organization\r
+.*""".format(**params)
+#dc: {DOMAIN}\r
+ if re.match(s, results['ldapsearch_before'], re.DOTALL):
+ score += 2
+ else:
+ hints += ["domain missing in ldapsearch result"]
+ s = ".*cn: {}.*".format(re.escape(params['LDAP_USERNAME']))
+ if re.search(s, results['ldapsearch_before']):
+ score += 2
+ else:
+ hints += ["LDAP_USERNAME missing in: " + s + str(results['ldapsearch_before'])]
+ fortune = kpov_util.hostname_gen(random.Random(str(params['LDAP_USERNAME'])))
+ s = ".*cn: {0}.*description: {1}.*".format(
+ re.escape(params['LDAP_USERNAME']), re.escape(fortune))
+ if re.match(s, results['ldapsearch_after'], re.DOTALL):
+ score += 2
+ else:
+ hints += ["description missing after update:" + fortune + "\n" + s + str(results['modify']) + str(results['ldapsearch_after'])]
+ if results['ldapsearch_before'][:100] == results['ldapsearch_after'][:100]:
+ score += 2
+ else:
+ hints += ["ldapsearch before equals after. This should not happen."]
+ s = '.*\r\nmodifying entry "cn={LDAP_USERNAME},ou=Users,dc={DOMAIN},dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si".*'.format(
+ **params)
+ if re.match(s, results['modify'], re.DOTALL):
+ score += 2
+ else:
+ hints += ['Modify error' + s + str(results['modify'])]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcpGWLDAP'], global_params)
diff --git a/tasks/mock_entrance_exam/howtos/en/index.html b/tasks/mock_entrance_exam/howtos/en/index.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/en/index.html
diff --git a/tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface1.jpg b/tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface1.jpg
new file mode 100644
index 0000000..8953de7
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface1.jpg
Binary files differ
diff --git a/tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface2.jpg b/tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface2.jpg
new file mode 100644
index 0000000..4eeb5e0
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/images/SimpleArbiter-interface2.jpg
Binary files differ
diff --git a/tasks/mock_entrance_exam/howtos/images/SimpleArbiter.jpg b/tasks/mock_entrance_exam/howtos/images/SimpleArbiter.jpg
new file mode 100644
index 0000000..4df497e
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/images/SimpleArbiter.jpg
Binary files differ
diff --git a/tasks/mock_entrance_exam/howtos/images/student-entrance-interface1.jpg b/tasks/mock_entrance_exam/howtos/images/student-entrance-interface1.jpg
new file mode 100644
index 0000000..3174913
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/images/student-entrance-interface1.jpg
Binary files differ
diff --git a/tasks/mock_entrance_exam/howtos/images/student-entrance-interface2.jpg b/tasks/mock_entrance_exam/howtos/images/student-entrance-interface2.jpg
new file mode 100644
index 0000000..5679dae
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/images/student-entrance-interface2.jpg
Binary files differ
diff --git a/tasks/mock_entrance_exam/howtos/images/student-entrance.jpg b/tasks/mock_entrance_exam/howtos/images/student-entrance.jpg
new file mode 100644
index 0000000..4df497e
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/images/student-entrance.jpg
Binary files differ
diff --git a/tasks/mock_entrance_exam/howtos/si/index.html b/tasks/mock_entrance_exam/howtos/si/index.html
new file mode 100644
index 0000000..f10bcf1
--- /dev/null
+++ b/tasks/mock_entrance_exam/howtos/si/index.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Preparation_mock_entrance_exam_HowTo</title>
+</head>
+<body><span style="font-family: Georgia, Times New Roman, Times, serif; ">
+ <strong><h1>MOCK ENTRANCE EXAM - HOWTO</h1></strong>
+
+<h2>1) POSTAVITEV VIRTUALK</h2>
+
+Najprej prenesi obe sliki za virtualki iz sistema kpov-judge, 2. naloga. Če se sliki ne naložita takoj, malo počakaj in osveži stran.
+Ustvari novo virtualko imenovano "Student", tip je načeloma "Linux" ter verzija "Ubuntu (64-bit)" - lahko pa je tudi karkoli drugega. Določi ustrezno količino pomnilnika, ki bo na voljo napravi, izberi možnost rabe obstoječe slike navidezne naprave ter izberi prenešeno datoteko "student-entrance.vdi". Klikni ustvari. <br> <img src="../images/student-entrance.jpg" alt="ni slike" width="600" height="400"></li> <br>
+Prejšnji postopek ponovi še za "SimpleArbiter", "Linux", "Ubuntu (64-bit)", "simplearbiter.vdi". <br> <img src="../images/SimpleArbiter.jpg" alt="ni slike" width="600" height="400"></li> <br>
+
+<h2>2) OMREŽNE NASTAVITVE VIRTUALK</h2>
+
+V navodilih naloge lahko vidimo, da morata biti obe virtualki povezani v internet ter povezani med seboj prek nekega notranjega omrežja.
+Na "SimpleArbiter" nastavimo pod Settings->Network->Adapter 1; Enable network adapter "check", Attached to: NAT. ->Adapter 2; Enable network adapter "check", Atached to: Internal Network. <br> <img src="../images/SimpleArbiter-interface1.jpg" alt="ni slike" width="600" height="400"></li> <img src="../images/SimpleArbiter-interface2.jpg" alt="ni slike" width="600" height="400"></li> <br>
+Na "Student" je postopek nastavitve enak kot na "SimpleArbiter". <br> <img src="../images/student-entrance-interface1.jpg" alt="ni slike" width="600" height="400"></li> <img src="../images/student-entrance-interface2.jpg" alt="ni slike" width="600" height="400"></li> <br>
+
+OPOMBA: Pozoren je treba biti, da sta oba vmesnika, ki sta povezana na notranje omrežje (Internal Nerwork) povezana preko istega omrežja, npr. "intnet".
+
+<h2>3) ZAGON VIRTUALK IN POSOTPEK NALOGE</h2>
+
+SA - SimpleArbiter
+STUD - Student
+
+Najprej zaženemo obe vritualki, to storimo s klikom na gumb start.
+Na SA se prijavimo z uporabniškim imenom "tester" ter geslom "tester"
+
+<h3>3.1) POSKRBIMO ZA MREŽO</h3>
+
+<h4>3.1.1) SPREMEMGA GESLA ZA ROOT</h4>
+
+Z uporabo ukaza /sbin/ifconfig preverimo, ali so vmesniki pravilno nastavljeni. Kaj kmalu ugotovimo, da je na SA aktiven samo en vmesnik. Za nastavljanje omesnikov moramo najprej postati "root", torej uporabnik, ki ima pooblastila za urejanje sistemskih nastavitev.
+Najprej ponovno zaženemo virtualko: "sudo reboot", potrdimo z geslom "tester".
+V GRUB meniju (zagonski meni) nato pritisnemo tipko "e", ki omogoča spreminjanje ukazov pred zagonom. Vrstico "53d ro" spremenimo v "53d rw init=/bin/bash". Pritisnemo "F10" in sprožimo zagon naprave.
+Sedaj lahko kot super uporabnik zamenjaš geslo za root, to storiš z ukazom "passwd", sistem te nato vpraša za novo geslo, po vnosu pa še za potrditev gesla. Geslo je uspešno spremenjeno, spremembe pa je potrebno še shraniti na disk, to storiš z ukazom "mount -o remount,ro /", izvedi še ukaz "sync", da se podatki res zapišejo na disk. Sedaj lahko virtualko ponovno zaženeš kar iz Machine->Reset.
+
+<h4>3.1.2) NASTAVIMO OMREŽNE VMESNIKE</h4>
+
+V virtualko SA se sedaj prijavimo kot uporabnik "root" ter s spremenjenim geslom "karsinastavil".
+Sedaj spremenimo nastavitve omrežnih vmesnikov tako, da bodo naslovi ustrezali tistim v navodilih. Izvedemo ukaz "ifconfig enp0s8 10.0.2.129 netmask 255.255.255.128 up"
+Preklopimo na virtualko STUD (uporabnik "root", geslo "kaboom") ter izvedemo podoben ukaz "ifconfig enp0s8 10.0.2.X netmassk 255.255.255.128", kjer je X podatek iz navodil naloge.
+Notranje omrežje testiramo tako, da pošljemo ping iz SA do STUD z ukazom "ping NASLOV", kjer je NASLOV omrežni naslov na STUD, ki je povezan na notranje omrežje (nastavitev iz prejšnjega koraka).
+SUPER, omrežje deluje, gremo naprej. Če ne deluje, preveri pravilnost naslovov na SA in STUD, bodi pozoren na dolžino maske ter na morebitne zatipke.
+
+<h3>3.2) "ZLONAMERNI" PROGRAM</h3>
+
+V navodilih naloge je podano ime programa, ki naj bi ob svojem zagonu pokvaril nastavitve omrežnih vmesnikov na STUD. Z ukazom "ps xa | grep IMEPROGRAMA" preverimo, če se program izvaja. V izpisu ugotovimo, da se najvrjetneje ne izvaja, zato lahko zadevo ignoriramo. Če bi se program izvajal, bi bilo potrebno ukrepati ter ga na nek način izbrisati oz. mu onemogočiti spreminjanje omrežnih vmesnikov (najlažje bi bilo uporabiti ukaz "kill", ki kot argument prejme PID (prvi stolpec prejšnjega izpisa) ter konča izvajanje tega procesa). Več o ukazu "kill" si preberi na spletu!
+
+<h3>3.3) PREVAJANJE PROGRAMA</h3>
+
+Najprej si odpremo novo konzolo na STUD "alt+F2" ter se prijavimo kot "student" z geslom "vaje".
+Z ukazom "ls" preverimo vsebino domačega direktorija uporabnika student. Izpisati bi se morala datoteka, ki jo imamo podano v navodilih. To datoteko moramo najprej odpreti z ukazom "vim IMEDATOTEKE". Datoteko moramo sedaj popraviti tako, da odstranimo odvečne črke, to storimo tako, da izvedemo ukaz ":%s/[QXW]*//g", sedaj izvedemo še ":syn on" in si obarvamo kodo. Izhod iz urejevalnika ":wq".
+Ta program sedaj z ukazom "gcc IMEPREVEDENEGAPROGRAMA IMEDATOTEKE" prevedemo v nov program, kjer je IMEPREVEDENEGAPROGRAMA izhodni program, katerega ime je prav tako podano v navodilih, IMEDATOTEKE pa ime pravkar popravljene datoteke.
+
+<h3>3.4) SKRIPTA</h3>
+
+Sedaj bomo napisali nov program/skripto, uporabimo urejevalnik nano; "nano IMESKRIPTE", kjer je IMESKRIPTE podano v navodilih naloge.
+V skripto zapišemo sledeče;<br>
+ <br>
+----BREZ TE VRSTICE-------<br>
+ <br>
+#!/bin/bash<br>
+<br>
+echo -n $SPREMENLJIVKA | /home/student/IMEPREVEDENEGAPROGRAMA "argument" 2> /home/student/IMEDATOTEKE_STDERR | grep "ma" > /home/student/IMEDATOTEKE_STDOUT<br>
+ <br>
+----BREZ TE VRSTICE-------<br>
+ <br>
+Datoteko shranimo "ctrl+x" ter potrdimo z "y" in enter.
+Datoteko sedaj spremenimo v program "chmod +x IMESKRIPTE"
+
+<h2>4) TESTIRANJE NALOGE</h2>
+
+Preklopimo nazaj na SA ter odpremo novo konzolo "alt+F2", vpišemo se kot uporabnik "tester" z geslom "tester" in poženemo program "./test_task.py"
+Izpolnimo vsa polja; URL "https://kpov.fri.uni-lj.si/kpov_judge/tasks", vpišemo svoje uporabniško ime in geslo (za dostop do KPOV-JUDGE preko učilnice) npr. "jn1234@student.uni-lj.si geslozaucilnico", ime naloge "02-preparation-mock_entrance_exam". Sedaj se pojavijo še vaši vhodni in izhodni podatki za nalogo, preverite, če so pravilni; datoteka z izhodom, IP naslov SA, ime spremenljivke, ime "zlonamernega" programa, datoteka z napakami ter neko naljučno seme itd.
+Če program vrne 10 OK je naloga uspešno opravljena, sicer pa vrne število doseženih točk ter napako.
+ </span>
+</body>
+</html>
diff --git a/tasks/mock_entrance_exam/task.py b/tasks/mock_entrance_exam/task.py
new file mode 100644
index 0000000..ad51c2a
--- /dev/null
+++ b/tasks/mock_entrance_exam/task.py
@@ -0,0 +1,313 @@
+# 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': '''\
+<p>
+Postavite dva navidezna računalnika - <em>SimpleArbiter</em> in <em>Student</em>. Oba naj bosta povezana na internet. Poleg tega mora biti <em>Student</em> na naslovu {{student_IP}} dostopen s <em>SimpleArbiter</em>.
+
+<p>
+Računajte, da se na <em>Student</em> ob zagonu zažene program {{net_prog_name}}, ki vam spreminja nastavitve mrežne kartice.
+
+<p>
+V domačem imeniku uporabnika <code>student</code> obstaja program <code>{{P_c}}</code> v programskem jeziku C.
+Prevedite ga v program z imenom <code>{{P_executable}}</code>. Izvorna koda je namenoma pokvarjena tako, da so vanjo vrinjeni nepotrebni znaki. Pred prevajanjem jo morate popraviti.
+
+<p>
+Napišite skripto ali program <code>{{P_script}}</code> v domačem imeniku uporabnika <code>student</code>, ki:
+
+<ul>
+<li>požene <code>{{P_executable}}</code> z argumentom <code>"{{arg_c}}"</code> in mu na standardni vhod pripelje vrednost spremenljivke <code>{{env_c}}</code>;
+<li>vse, kar <code>{{P_executable}}</code> izpiše na stderr, spravi v datoteko <code>{{out_stderr_c}}</code>; in
+<li>vse vrstice, ki jih <code>{{P_executable}}</code> izpiše na stdout in vsebujejo zaporedje znakov <code>ma</code>, zapiše v <code>{{out_stdout_c}}</code>.
+</ul>
+
+<p>
+Lastnik vseh ustvarjenih datotek mora biti uporabnik <code>student</code>. Gesla uporabnika <code>student</code> (<code>vaje</code>) ne smete spreminjati.
+''',
+ 'en': '''\
+<p>
+Set up two virtual machines - <em>SimpleArbiter</em> and <em>Student</em>. Both should be connected to the internet. <em>Student</em> should also be accessible from <em>SimpleArbiter</em> at the address <code>{{student_IP}}</code>.
+
+<p>
+Keep in mind that a program called <code>{{net_prog_name}}</code> starts on <em>Student</em> on each boot. This program may change your network settings.
+
+<p>
+There is a program called <code>{{P_c}}</code> in <code>student</code>’s home directory. Compile it into a program called <code>{{P_executable}}</code>. The source code is intentionally broken so that unneccessarry characters are inserted into the file. You have to fix the file before compiling.
+
+<p>
+Also, write a script or program called <code>{{P_script}}</code> in <code>student</code>’s home directory. The script should:
+
+<ul>
+<li>run <code>{{P_executable}}</code> with the argument <code>{{arg_c}}</code> and pipe the value of the environment variable <code>{{env_c}}</code> into <code>{{P_executable}}</code>’s standard input;
+<li>redirect stderr of <code>{{P_executable}}</code> into a file called <code>{{out_stderr_c}}</code>; and
+<li>save each line which <code>{{P_executable}}</code> outputs and which contains the character sequence <code>ma</code> into <code>{{out_stdout_c}}</code>.
+</ul>
+
+<p>
+The owner of all created files should be <code>student</code>. You are not allowed to change <code>student</code>’s password (<code>vaje</code>).
+''',
+}
+
+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<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+/* Odstranite vse odvecne velike crke Q, W ali X in program se bo prevedel. */
+
+int main(int argc, char **argv){
+ unsigned char *arg;
+ unsigned char var[255];
+ int i, arg_len, env_len, r;
+ scanf("%s", var);
+ arg = argv[1];
+ arg_len = strlen(argv[1]);
+ env_len = strlen(var);
+ r = 0;
+ for (i = 0; i<100; i++){
+ printf("%c", 32 + (arg[i % arg_len] ^ var[i % env_len]) % 64);
+ r += (int)arg[i % arg_len] + (int)var[i % env_len] + i;
+ if (i % 17 == 0){
+ printf("RAUS\\n");
+ }
+ if (i % 29 == 0){
+ printf("ma");
+ }
+ fprintf(stderr, "%c", (r % 31) + 'A');
+ if (i % 23 == 0){
+ fprintf(stderr, "PATACIS\\n");
+ }
+ }
+ printf("\\n");
+ fprintf(stderr, "\\n");
+ return r % 16;
+}
+'''
+ evil_shell_source = """#!/bin/bash -e
+
+while true; do
+ /sbin/ifconfig eth1 10.0.4.19 2> /dev/null;
+ /sbin/ifconfig eth0 10.0.4.20 2> /dev/null;
+ /sbin/ifconfig eth2 10.0.4.21 2> /dev/null;
+ /sbin/ifconfig en0p3 10.0.4.19 2> /dev/null;
+ /sbin/ifconfig en0p8 10.0.4.20 2> /dev/null;
+ /sbin/ifconfig enp0s3 10.0.4.21 2> /dev/null;
+ /sbin/ifconfig enp0s8 10.0.4.21 2> /dev/null;
+ sleep 10;
+done;
+"""
+ import random
+ d = templates['student-entrance']
+ r = random.Random(task_params['c_destroy_gen_seed'])
+ destroyed_c_source = c_source[:110]
+ for c in c_source[110:]:
+ i = r.randint(0, 5)
+ if i == 1:
+ destroyed_c_source += 'QW'
+ if i == 2:
+ destroyed_c_source += 'XW'
+ if i == 3:
+ destroyed_c_source += 'QX'
+ destroyed_c_source += c
+ d.write(task_params['P_c'], destroyed_c_source)
+ d.chown(1000, 1000, task_params['P_c'])
+ sh_path = r.choice(['/usr/share/doc', '/var/lib', '/usr/local/share', '/etc/alternatives'])
+ sh_file = sh_path + '/' + task_params['net_prog_name']
+ d.write(sh_file, evil_shell_source)
+ d.chmod(0o775, sh_file)
+ d.write("/etc/rc.local", """#!/bin/sh -e
+export PATH=$PATH:{}
+nohup {} &
+
+exit 0
+""".format(sh_path, task_params['net_prog_name']))
+
+ write_default_config(templates['simpleArbiter'], global_params)
diff --git a/tasks/nat_port_forward/task.py b/tasks/nat_port_forward/task.py
new file mode 100644
index 0000000..80d2e47
--- /dev/null
+++ b/tasks/nat_port_forward/task.py
@@ -0,0 +1,172 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavi tri računalnike - SimpleArbiter z diska simpleArbiter, TestClient z diska testClient in NATServer. NATServer naj ima dva omrežna vmesnika - z enim naj bo
+povezan na omrežje, od koder bo imel dostop do Interneta, z drugim pa na SimpleArbiter. TestClient naj bo povezan na isto omrežje z dostopom do Interneta kot NATServer.
+Poskrbi, da bo NATServer služil kot DHCP strežnik ter privzeti prehod za SimpleArbiter.
+Na SimpleArbiter preberi vrednosti NET, PORT_OUTER in PORT_INNER ter vpiši IP_TEST_CLIENT. Poskrbi, da
+bo omrežje med SimpleArbiter in NATServer na področju NET. Nato poskrbi, da se
+bo TCP promet z omrežja z dostopom do Interneta na vrata PORT_OUTER prepošiljal na SimpleArbiter na vrata PORT_INNER.</pre>"""
+}
+
+computers = {
+ 'TestClient': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'NATServer': {
+ 'disks': [
+ { 'name': 'student-NATServer',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiter',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_TEST_CLIENT': {'descriptions': {'si': 'Naslov TestClient'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'IP_NAT': {'descriptions': {'si': 'Naslov NATServer, dostopen s TestClient'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'PORT_OUTER': {'descriptions': {'si': 'Zunanja vrata'}, 'w': False, 'public':True, 'type': 'port', 'generated': True},
+ 'PORT_INNER': {'descriptions': {'si': 'Notranja vrata'}, 'w': False, 'public': True, 'type': 'port', 'generated': True},
+ 'NET': {'descriptions': {'si': 'Področje naslovov med SimpleArbiter in TestClient'}, 'w': False, 'public': True, 'type': 'NET', 'generated': True},
+}
+
+def task(IP_TEST_CLIENT, IP_NAT, PORT_OUTER, PORT_INNER, NET):
+ import random
+ import time
+ import pexpect
+ from pexpect import pxssh
+
+ results = dict()
+ tcpdump = pexpect.spawn('sudo /usr/sbin/tcpdump src host {} and dst port {}'.format(IP_TEST_CLIENT, PORT_INNER), encoding='utf-8')
+ sshconn = pxssh.pxssh(encoding='utf-8')
+ sshconn.login(IP_TEST_CLIENT, 'student', 'vaje')
+ r = random.Random()
+ k = r.randint(10, 15)
+ results['pre_nc'] = str(k)
+ results['nc_pre'] = ""
+ for i in range(k):
+ sshconn.sendline("nc {} {}".format(IP_NAT, PORT_OUTER))
+ sshconn.sendline()
+ sshconn.sendintr()
+ sshconn.prompt()
+ results['nc_pre'] += sshconn.before
+ nc = pexpect.spawn('nc -l -p {}'.format(PORT_INNER), encoding='utf-8')
+ sshconn.sendline()
+ sshconn.prompt()
+ sshconn.sendline("nc {} {}".format(IP_NAT, PORT_OUTER))
+ results['post_nc'] = "".join([r.choice("abcd\n") for i in range(100)])
+ sshconn.sendline(results['post_nc'])
+ time.sleep(1)
+ sshconn.sendintr()
+ nc.expect(pexpect.EOF)
+ results['nc_ret'] = nc.before
+ results['route'] = pexpect.run('ip route list 0/0', encoding='utf-8')
+ results['traceroute'] = pexpect.run('traceroute {}'.format(IP_TEST_CLIENT), encoding='utf-8')
+ # wait for traceroute
+ time.sleep(10)
+ tcpdump.sendintr()
+ tcpdump.expect(pexpect.EOF)
+ results['tcpdump'] = tcpdump.before
+ sshconn.prompt()
+ results['nc_post'] = sshconn.before
+ sshconn.close()
+ # nc.expect(pexpect.EOF)
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ params['PORT_INNER'] = str(r.randint(6000, 10000))
+ params['PORT_OUTER'] = str(r.randint(10001, 15000))
+ params['NET'] = kpov_util.IPv4_subnet_gen(r, "10.36.0.0/14", 24)
+ return params
+
+def task_check(results, params):
+ import re
+ import pickle
+ score = 0
+ hints = []
+ local_net = params['NET'][:params['NET'].rfind('.')]
+ s = "default via ({}\\.[0-9]+)".format(re.escape(local_net))
+ res = re.search(s, results['route'])
+ if res:
+ ip_nat_internal = res.groups(1)[0]
+ score += 1
+ else:
+ ip_nat_internal = 'abrakadabra'
+ # print (s, results['route'],)
+ s = "traceroute to {ip_test} \\({ip_test}\\), 30 hops max, 60 byte packets\
+\r\n 1 {ip_nat} \\({ip_nat}\\) [0-9.]+ ms [0-9.]+ ms [0-9.]+ ms\
+.*{ip_test} \\({ip_test}\\)".format(
+ ip_nat = re.escape(ip_nat_internal),
+ ip_test = re.escape(params['IP_TEST_CLIENT'])
+ )
+ if re.search(s, results['traceroute'], re.DOTALL):
+ score += 1
+ else:
+ hints += [s + str(results['traceroute'])]
+ if len(results['post_nc']) == 100:
+ score += 1
+ else:
+ hints += [str(results['post_nc']) + str(len(results['post_nc']))]
+ if results['nc_ret'] == (results['post_nc'] + '\n').replace('\n', '\r\n'):
+ score += 1
+ else:
+ hints += ['wrong nc']
+ s = "Connection refused"
+ res = re.findall(s, results['nc_pre'])
+ if len(res) >= 2:
+ score += 3
+ else:
+ hints += [s + str(results['nc_pre'])]
+ s = "\r\n"
+ if re.search(s, results['nc_post']):
+ score += 1
+ else:
+ hints += [s + str(results['nc_post'])]
+ rejected_count = int(results['pre_nc'])
+ accepted_count = results['nc_ret'].count('\r\n')
+ s = ".*verbose output suppressed.*listening on.*dropped by kernel.*"
+ if re.match(s, results['tcpdump'], re.DOTALL):
+ score += 1
+ else:
+ hints += [s + str(results['tcpdump'])]
+ res = re.findall("length .*\r\n", results['tcpdump'])
+ total_len = 0
+ n_empty = 0
+ for i in res:
+ k = int(i[len("length "):].strip())
+ total_len += k
+ if k == 0:
+ n_empty += 1
+ # print total_len, rejected_count, n_empty
+ if total_len == 101 and rejected_count <= n_empty:
+ score += 1
+ else:
+ hints += [s + str(results['tcpdump'])]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiter'], global_params)
diff --git a/tasks/nat_vlc/howtos/en/index.html b/tasks/nat_vlc/howtos/en/index.html
new file mode 100644
index 0000000..6048647
--- /dev/null
+++ b/tasks/nat_vlc/howtos/en/index.html
@@ -0,0 +1,72 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+<strong><h1>NAT VLC:</h1></strong>
+<p><strong><h2>Explanation:</h2></strong><br>
+ Set up a computer so that it forwards all packets meant for a certain address, to another computer.</p>
+<p><strong><h2>Instructions:</h2></strong>
+ <h3>1. Create two VMs. SimpleArbiter using the disk simpleArbiter and NATServer. </h3>
+ You can get the disks at polz.si/media/uploads/kpov/virtualke. As for the NATServer VM, you can use any disk you want like base-student-desktop-2014.
+<br>
+ <h3>2. NATServer should have two network interfaces, one should connect to the simpleArbiter VM and the other to the internet.</h3>
+ Adapter 1 should be NAT and adapter 2 should be Internal Network.<br>
+ Simple Arbiter must be connected to the Internal Network.
+<br>
+ <img style="width: 500px; height: 310px;" src="../images/1.jpg" alt="slika-1"></img>
+ <h3>3.On NATServer use ifconfig or /etc/network/interfaces to configure the network interfaces you created in virtualbox.<br></h3>
+
+ -vim /etc/network/interfaces<br>
+ -Set it up like this:<br>
+ auto eth1<br>
+ iface eth1 inet static<br>
+ NETMASK 255.255.0.0 # Specify based on your requirement<br>
+ IPADDR 192.168.2.1 # Gateway of the LAN<br>
+ NETWORK 192.168.0.0 # Optional<br>
+ ADDRESS 192.168.0.0 <br>
+ -ifdown eth1<br>
+ -ifup eth1
+<br>
+<img style="width: 500px; height: 310px;" src="../images/2.jpg" alt="slika-2"></img>
+ <h3>4. Configure SimpleArbiter so that it uses NATServer as the default gateway.</h3>
+
+ <h3> 5. Set up DNS (etc/resolv.conf) on NATServer.</h3>
+ vim /etc/resolv.conf
+ nameserver 203.145.184.13 # Primary DNS Server provided by the ISP<br>
+ nameserver 202.56.250.5 # Secondary DNS Server provided by the ISP<br>
+ Than we set up the host:<br>
+ vim /etc/hosts<br>
+ Replace the first line with:<br>
+ 127.0.0.1 nat localhost.localdomain localhost<br>
+
+ <h3>6. Enable IP forwarding on NATServerju (should be run as root).</h3>
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ <h3>7. Set up NAT on NATServer using iptables.</h3>
+
+ apt-get install iptables<br>
+ iptables -F<br>
+ ptables -t nat -F<br>
+ iptables -t mangle -F <br>
+ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE<br>
+ iptables -A FORWARD -i eth1 -j ACCEPT<br><br>
+
+ service iptables restart
+
+ <h3>8. Use vlc on simpleArbiter to watch the video over your network. </h3> <br>
+
+
+ <h3>8. Additional resources </h3> <br>
+-https://www.howtoforge.com/nat_iptables<br>
+-http://www.bctes.com/nat-linux-iptables.html<br>
+
+
+
+
+
+</body>
+
+</html>
diff --git a/tasks/nat_vlc/howtos/images/1.jpg b/tasks/nat_vlc/howtos/images/1.jpg
new file mode 100644
index 0000000..adee258
--- /dev/null
+++ b/tasks/nat_vlc/howtos/images/1.jpg
Binary files differ
diff --git a/tasks/nat_vlc/howtos/images/2.jpg b/tasks/nat_vlc/howtos/images/2.jpg
new file mode 100644
index 0000000..f7868df
--- /dev/null
+++ b/tasks/nat_vlc/howtos/images/2.jpg
Binary files differ
diff --git a/tasks/nat_vlc/howtos/si/index.html b/tasks/nat_vlc/howtos/si/index.html
new file mode 100644
index 0000000..779cd54
--- /dev/null
+++ b/tasks/nat_vlc/howtos/si/index.html
@@ -0,0 +1,80 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+<strong><h1>NAT VLC:</h1></strong>
+<p><strong><h2>Naloga na hitro:</h2></strong><br>
+ Nastavi računalnik tako, da bo vse pakete za določene naslove prepošiljal na drug računalnik, vzpostavi NAT.</p>
+<p><strong><h2>Navodila:</h2></strong>
+ <h3>1. Postavi dva navidezna računalnika. SimpleArbiter z diskom simpleArbiter ter NATServer. </h3>
+ Virtualke dobiš na (polz.si/media/uploads/kpov/virtualke). Za NATServer lahko uporabiš base-student-desktop-2014.
+<br>
+ <h3>2. Postavi NAT server tako, da ima dva omrežna vmesnika. Z enim naj bo povezan na simpleArbiter, z drugim pa na internet.</h3>
+ (settings-Network) Adapter 1 nastavimo na NAT (omrežje), adapter 2 pa na InternalNetwork (lokalno).<br>
+ Simple Arbiter nastavimo na InternalNetwork(lokalno).
+<br>
+ <img style="width: 500px; height: 310px;" src="../images/1.jpg" alt="slika-1"></img>
+ <h3>3.Na NATServer z ukazom ifconfig in z datoteko /etc/network/interfaces skonfiguriraj omrežne vmesnike<br>
+ tako, da bo en povezan v WAN (internet) in en vmesnik na LAN (simpleArbiter).</h3>
+
+ -vim /etc/network/interfaces<br>
+ -dopišemo:<br>
+ auto eth1<br>
+ iface eth1 inet static<br>
+ NETMASK 255.255.0.0 # Specify based on your requirement<br>
+ IPADDR 192.168.2.1 # Gateway of the LAN<br>
+ NETWORK 192.168.0.0 # Optional<br>
+ ADDRESS 192.168.0.0 <br>
+ -ifdown eth1<br>
+ -ifup eth1
+<br>
+<img style="width: 500px; height: 310px;" src="../images/2.jpg" alt="slika-2"></img>
+ <h3>4. SimpleArbiter skofiguriraj tako, da bo privzeti prehod uporabljal NATServer.</h3>
+ Nastavi gateway, da ima IP od NATServerja.<br>
+ route add -net IP netmask MASK default gw IP dev eth0<br>
+
+ <h3> 5. Nastavi DNS (etc/resolv.conf) na NATServerju.</h3>
+ vim /etc/resolv.conf
+ nameserver 203.145.184.13 # Primary DNS Server provided by the ISP<br>
+ nameserver 202.56.250.5 # Secondary DNS Server provided by the ISP<br>
+ Nato nastavimo še host:<br>
+ vim /etc/hosts<br>
+ Prvo vrstico zamenjamo z:<br>
+ 127.0.0.1 nat localhost.localdomain localhost<br>
+
+ <h3>6. Omogoči posredovanje IP naslovov na NATServerju.</h3>
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ <h3>7. Nastavi NAT z uporabo paketa iptables na NATServerju.</h3>
+
+ apt-get install iptables<br>
+ iptables -F<br>
+ ptables -t nat -F<br>
+ iptables -t mangle -F <br>
+ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE<br>
+ iptables -A FORWARD -i eth1 -j ACCEPT<br><br>
+
+ service iptables restart
+
+ <h3>8. Na simpleArbiter z vlc preberi naslov, na katerem si lahko ogledaš kratek filmček. </h3>
+
+ apt-get install vlc-nox<br>
+ Nastavitev naslova:<br>
+ Open Media > OpenNetwork ....<br>
+
+
+
+ <h3>8. Dodatni viri </h3> <br>
+-https://www.howtoforge.com/nat_iptables<br>
+-http://www.bctes.com/nat-linux-iptables.html<br>
+
+
+
+
+
+</body>
+
+</html>
diff --git a/tasks/nat_vlc/task.py b/tasks/nat_vlc/task.py
new file mode 100644
index 0000000..5224495
--- /dev/null
+++ b/tasks/nat_vlc/task.py
@@ -0,0 +1,126 @@
+# kpov_util should be imported by add_assignment.py
+
+# Poglej nek film na nekem določenem URL.
+# (?md5 vsota filma?)
+
+# Nastavi nek računalnik tako, da bo izvajal NAT.
+#TODO: finish this
+
+instructions = {
+ 'si': '''\
+<p>
+Postavi dva navidezna računalnika: <em>SimpleArbiter</em> in <em>NATServer</em>. <em>NATServer</em> naj ima dva omrežna vmesnika - z enim naj bo povezan na lokalno omrežje, na katerem naj bo tudi simpleArbiter, z drugim pa na Internet.
+
+<p>
+Na <em>NATServer</em> skonfiguriraj omrežne vmesnike tako, da bo imel dostop do Interneta in da bo imel na lokalnem omrežju <code>{{IP_NAT}}</code>. Na <em>NATServer</em> ustvarite še uporabnika <code>{{IP_NAT_user}}</code>.
+
+<p>
+Poskrbi, da bo <em>SimpleArbiter</em> prek DHCP dobil naslov <code>{{IP_simple}}</code>. Poskrbi, da bo <em>NATServer</em> deloval kot prehod za <em>SimpleArbiter</em> in izvajal NAT.
+''',
+ 'en': '''\
+<p>
+Set up two virtual machines: <em>SimpleArbiter</em> and
+<em>NATServer</em>. <em>NATServer</em> should have two network
+adapters. Connect the first adapter to <em>SimpleArbiter</em> and the
+second adapter to the Internet.
+
+<p>
+Configure the network in <em>NATServer</em> so that one interface is connected to the Internet while the other is connected to <em>SimpleArbiter</em> and has the address <code>{{IP_NAT}}</code>. Create a user called <code>{{IP_NAT_user}}</code> on <em>NATServer</em>.
+
+<p>
+Configure a DHCP server on <em>NATServer</em> so that <em>SimpleArbiter</em> gets the IP <code>{{IP_simple}}</code>. Also, set up NAT on <em>NATServer</em> and set it as the gateway for <em>SimpleArbiter</em>.
+''',
+}
+
+computers = {
+ 'NATServer': {
+ 'disks': [
+ { 'name': 'student-NATServer',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiter',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+#ne potrebujemo dnsjev in ip za malibreznewtork manager?
+params_meta = {
+ 'IP_simple': {'descriptions': {'si': 'Naslov SimpleArbiter', 'en': 'SimpleArbiter address'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_NAT': {'descriptions': {'si': 'Naslov NATServer', 'en': 'NATServer address'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True },
+ 'IP_NAT_user': {'descriptions': {'si': 'Username na NATServer', 'en': 'Username on NATServer'}, 'w': False, 'public' : True, 'type' : 'username', 'generated' : True},
+ 'IP_NAT_passwd': {'descriptions': {'si': 'Password na NATServer', 'en': 'Password on NATServer'}, 'w': True,'public' : True, 'type' : 'passwd', 'generated' : False},
+}
+
+def task(IP_simple, IP_NAT, IP_NAT_user, IP_NAT_passwd):
+ import pexpect
+
+ results = kpov_util.ssh_test(IP_NAT, IP_NAT_user, IP_NAT_passwd, (
+ ('IP_NAT_ip_forward', 'cat /proc/sys/net/ipv4/ip_forward'),
+ ))
+
+ # Check if If IP_simple is connected to NAT
+ results['IP_simple_ping_to_NAT'] = pexpect.run('ping -c 5 {}'.format(IP_NAT), encoding='utf-8')
+ # Check routing table on IP_simple
+ results['IP_simple_routing_table'] = pexpect.run('route -n', encoding='utf-8', env={'PATH': '/bin:/sbin'})
+ # Tracert Check if IP_simple is connected to internet
+ results['IP_simple_to_internet'] = pexpect.run('traceroute 8.8.8.8', encoding='utf-8')
+
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ # dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_net_gen(r, 253, True, False)
+ # params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NAT'], params['IP_simple'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['IP_NAT_user'] = kpov_util.default_generators['username'](r)
+ # params['IP_NM']
+ # params['IP_simple'] = kpov_util.IPv4_addr_gen(r, net, 1)
+ # params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+ if re.search(
+ "PING.*\r\n64 bytes from {}: icmp_seq=[0-9]+ ttl=64 time=[0-9.]* ms".format(
+ params['IP_NAT']), results['IP_simple_ping_to_NAT']):
+ score += 3
+ else:
+ hints.append("Ping to NAT incorrect")
+ if results['IP_NAT_ip_forward'].strip() == "1":
+ score += 2
+ else:
+ hints.append("ip_forward not set on NAT?")
+ rs = r"1 +{0} +\({0}\)".format(params['IP_NAT'])
+ if re.search(rs,
+ results['IP_simple_to_internet']):
+ score += 3
+ else:
+ hints.append("traceroute not OK")
+ gateway=r'0\.0\.0\.0 +{} +0\.0\.0\.0 +UG'.format(params['IP_NAT'].replace('.', '\.'))
+ if re.search(gateway,results['IP_simple_routing_table']) and \
+ re.search("Kernel IP routing table\r\nDestination", results['IP_simple_routing_table']):
+ score += 2
+ else:
+ hints.append("route not OK")
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiter'], global_params)
+
diff --git a/tasks/nat_vlc/video.py b/tasks/nat_vlc/video.py
new file mode 100644
index 0000000..3c21c82
--- /dev/null
+++ b/tasks/nat_vlc/video.py
@@ -0,0 +1,37 @@
+import string, random, os
+#You need to find PIL library on the internet. Just GOOGLE it!!! Other imports are standard.
+from PIL import Image, ImageDraw, ImageFont
+
+#Method for generating random string
+def randomString():
+ return ''.join(random.choice(string.lowercase) for i in range(30))
+
+
+image = Image.new("RGBA", (600,150), (255,255,255))
+draw = ImageDraw.Draw(image)
+
+#Font option is optional. If you don't want to use it figure out how to increase font size, because default is veeeeery small.
+
+font = ImageFont.truetype("georgia.ttf", 36)
+txt = randomString()
+
+draw.text((20,50), txt, (20,100,0), font)
+img_resized = image.resize((600,80), Image.ANTIALIAS)
+img_resized.save("out.png")
+
+#Creates .mp4 video from image out.png. Video is 1 second long.
+bashCommand = "avconv -r 1/5 -i out.png -b:v 1000k video.mp4"
+os.system(bashCommand)
+
+# Converts .mp4 video to .avi format. Still 1 second long. ( 2x )
+bashCommand = "avconv -i video.mp4 -c:a copy video.avi"
+os.system(bashCommand)
+
+bashCommand = "avconv -i video.mp4 -c:a copy video1.avi"
+os.system(bashCommand)
+
+# This loop will increas videos length by adding more picesec of the original video.
+last = int(input("Set video length in seconds: "))
+bashCommand = "avconv -i concat:video.avi\|video1.avi -c copy video.avi"
+for i in range(0, last-2):
+ os.system(bashCommand)
diff --git a/tasks/network_boot_custom_program/task.py b/tasks/network_boot_custom_program/task.py
new file mode 100644
index 0000000..e3fbad2
--- /dev/null
+++ b/tasks/network_boot_custom_program/task.py
@@ -0,0 +1,119 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavi tri navidezne računalnike - simpleArbiter, DHCP_server, DHCP_client.
+Na računalniku DHCP_server najdeš program A. DHCP_server nastavi tako, da se bo
+DHCP_client lahko zagnal prek mreže. Na datotečni sistem, s katerega
+se zaganja DHCP_client, spravi program A. Poskrbi, da se A požene ob zagonu DHCP_client.
+
+DHCP_client ne sme imeti priklopljenega nobenega trdega diska.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ #{ 'name': 'CDROM',
+ # 'options':{'readonly': True},
+ # 'parts': [],# no parts, no mounting.
+ #}
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ #{ '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_NM': {'descriptions': {'si': 'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+# d = templates['simpleArbiterDhcp']
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
+
diff --git a/tasks/openvpn_multiple_hops/task.py b/tasks/openvpn_multiple_hops/task.py
new file mode 100644
index 0000000..44ad8c4
--- /dev/null
+++ b/tasks/openvpn_multiple_hops/task.py
@@ -0,0 +1,317 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavi 4 navidezne računalnike - SimpleArbiter z diska simpleArbiterDhcp, A, B ter C.
+Na računalnikih A, B in C ustvari uporabnika test z geslom test.
+Poskrbi, da bodo vsi štirje na istem navideznem fizičnem omrežju. Naslov omrežja (NET_PHYS) ter naslove
+(IP_A, IP_B, IP_C) preberi na SimpleArbiter. S pomočjo OpenVPN postavi navidezno omrežje med A in B na naslovih NET_VPN1.
+Nato s pomočjo OpenVPN postavi še navidezno omrežje med B in C na naslovih NET_VPN2.
+Poskrbi, da bo promet z A prek VPN prišel do C in obratno. Za avtentikacijo uporabi skupne skrivnosti, ki
+jih prebereš na SimpleArbiter - med A in B SECRET_AB ter med B in C SECRET_BC.</pre>
+"""
+}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ {
+ 'name': 'simpleArbiterDhcp',
+ }
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'nat'
+ },
+ {
+ 'network': 'net1'
+ }
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'VPNClient1': {
+ 'disks': [
+ {
+ 'name': 'student-VPNClient1',
+ }
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1'
+ },
+ {
+ 'network': 'vpnAB'
+ }
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'VPNClient2': {
+ 'disks': [
+ {
+ 'name': 'student-VPNClient2',
+ }
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1'
+ },
+ {
+ 'network': 'vpnAB'
+ },
+ {
+ 'network': 'vpnBC'
+ }
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'VPNClient3': {
+ 'disks': [
+ {
+ 'name': 'student-VPNClient3',
+ }
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1'
+ },
+ {
+ 'network': 'vpnBC'
+ }
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = {
+ 'nat': {
+ 'public': True
+ },
+
+ 'net1': {
+ 'public': True
+ },
+ # Used for VPN
+ 'vpnAB': {
+ 'public': False
+ },
+
+ 'vpnBC': {
+ 'public': False
+ }
+}
+#Tukaj sem generiral osem parametrov, prosil bi če se upoštevali pri Tasku.
+params_meta = {
+ 'IP_VPNClient1': {'descriptions':{'si':'IP klienta A na VPN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_LANClient1': {'descriptions':{'si':'IP klienta A na LAN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
+ 'IP1_VPNClient2': {'descriptions':{'si':'1. IP klienta B na VPN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP2_VPNClient2': {'descriptions':{'si':'2. IP klienta B na VPN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_LANClient2': {'descriptions':{'si':'IP klienta B na LAN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
+ 'IP_VPNClient3': {'descriptions':{'si':'IP klienta C na VPN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_LANClient3': {'descriptions':{'si':'IP klienta C na LAN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
+ 'IP_SimpleArbiterLAN': {'descriptions':{'si':'IP za SimpleArbiter na LAN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False}
+}
+
+
+def task(IP_SimpleArbiterLAN, IP_VPNClient1, IP_LANClient1, IP1_VPNClient2, IP2_VPNClient2, IP_LANClient2, IP_VPNClient3, IP_LANClient3):
+ tests = {
+ ('VPNClient1', IP_LANClient1): [
+ ('VPNClient1_ping_C2', 'ping -c 3 {}'.format(IP1_VPNClient2)),
+ ('VPNClient1_ping_C3', 'ping -c 3 {}'.format(IP_VPNClient3)),
+ ('VPNClient1_traceroute_C3', 'traceroute {}'.format(IP_VPNClient3)),
+ ],
+ ('VPNClient2', IP_LANClient2): [
+ ('VPNClient2_ping_C1', 'ping -c 3 {}'.format(IP_VPNClient1)),
+ ('VPNClient2_ping_C3', 'ping -c 3 {}'.format(IP_VPNClient3)),
+ ],
+ ('VPNClient3', IP_LANClient3): [
+ ('VPNClient3_ping_C1', 'ping -c 3 {}'.format(IP_VPNClient1)),
+ ('VPNClient3_ping_C2', 'ping -c 3 {}'.format(IP2_VPNClient2)),
+ ('VPNClient3_traceroute_C1', 'traceroute {}'.format(IP_VPNClient1)),
+ ],
+ }
+
+ for (name, host), host_tests in tests.items():
+ host_tests += [
+ (name+'_ifconfig', '/sbin/ifconfig -a'),
+ (name+'_route', '/sbin/route -n'),
+ ]
+
+ results = collections.defaultdict(str)
+ for (name, host), host_tests in tests.items():
+ results.update(kpov_util.ssh_test(host, 'test', 'test', host_tests))
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ import random
+ r = random.Random(user_id)
+ net = kpov_util.IPv4_subnet_gen(r, '10.70.0.0/16', 24)
+ params['IP_VPNClient1'], params['IP1_VPNClient2'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ net = kpov_util.IPv4_subnet_gen(r, '10.50.0.0/16', 24)
+ params['IP_VPNClient3'], params['IP2_VPNClient2'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ return params
+
+def task_check(results, params):
+
+ import re
+ score = 0
+ hints = []
+
+ IP_C1 = params['IP_VPNClient1'].replace('.', '\.')
+ IP1_C2 = params['IP1_VPNClient2'].replace('.', '\.')
+ IP2_C2 = params['IP2_VPNClient2'].replace('.', '\.')
+ IP_C3 = params['IP_VPNClient3'].replace('.', '\.')
+
+ # testi za ifconfig
+ # C1
+ rs = r"tun0.*\n.*inet.*{}".format(IP_C1)
+ if re.search(rs,
+ results['VPNClient1_ifconfig']):
+ score += 1
+ else:
+ hints.append("ifconfig on VPNClient1 is not OK")
+ pass
+ # C2
+ rs = r"tun.*\n.*inet.*{}".format(IP1_C2)
+ if re.search(rs, results['VPNClient2_ifconfig']):
+ rs = r"tun.*\n.*inet.*{}".format(IP2_C2)
+ if re.search(rs, results['VPNClient2_ifconfig']):
+ score += 1
+ else:
+ hints.append("ifconfig on VPNClient2 is not OK")
+ pass
+ else:
+ hints.append("ifconfig on VPNClient2 is not OK")
+ pass
+ # C3
+ rs = r"tun0.*\n.*inet.*{}".format(IP_C3)
+ if re.search(rs, results['VPNClient3_ifconfig']):
+ score += 1
+ else:
+ hints.append("ifconfig on VPNClient3 is not OK")
+ pass
+ # testi za route
+ # C1
+ rs = r"{}.*tun0".format(IP1_C2)
+ if IP_C3[:-1].endswith('.'):
+ ASD = IP_C3[:-1]+"0"
+ elif IP_C3[:-2].endswith('.'):
+ ASD = IP_C3[:-2]+"0"
+ else:
+ ASD = IP_C3[:-3]+"0"
+ if re.search(rs, results['VPNClient1_route']):
+ rs = r"{} {}.*tun0".format(ASD, IP1_C2)
+ if re.search(rs, results['VPNClient1_route']):
+ score += 1
+ else:
+ hints.append("route on VPNClient1 is not OK")
+ else:
+ hints.append("route on VPNClient1 is not OK")
+ pass
+ # C2
+ rs = r"{}.*tun".format(IP_C1)
+ if re.search(rs, results['VPNClient2_route']):
+ rs = r"{}.*tun".format(IP_C3)
+ if re.search(rs, results['VPNClient2_route']):
+ score += 1
+ else:
+ hints.append("route on VPNClient2 is not OK")
+ else:
+ hints.append("route on VPNClient2 is not OK")
+ pass
+ # C3
+ rs = r"{}.*tun0".format(IP2_C2)
+ if IP_C1[:-1].endswith('.'):
+ ASD = IP_C1[:-1]+"0"
+ elif IP_C1[:-2].endswith('.'):
+ ASD = IP_C1[:-2]+"0"
+ else:
+ ASD = IP_C1[:-3]+"0"
+ if re.search(rs, results['VPNClient3_route']):
+ rs = r"{} {}.*tun0".format(ASD, IP2_C2)
+ if re.search(rs, results['VPNClient3_route']):
+ score += 1
+ else:
+ hints.append("route on VPNClient3 is not OK")
+ else:
+ hints.append("route on VPNClient3 is not OK")
+ pass
+ # testi za ping
+ # C1
+ rs = r"64 bytes from {}: icmp_seq=[0-9]+ ttl=[0-9]+ time=\d+\.\d+ ms".format(IP1_C2)
+ if re.search(rs, results['VPNClient1_ping_C2']):
+ score += 0.5
+ else:
+ hints.append("ping from VPNClient1 to VPNClient2 is not OK")
+ pass
+ rs = r"64 bytes from {}: icmp_seq=[0-9]+ ttl=[0-9]+ time=\d+\.\d+ ms".format(IP_C3)
+ if re.search(rs, results['VPNClient1_ping_C3']):
+ score += 0.5
+ else:
+ hints.append("ping from VPNClient1 to VPNClient3 is not OK")
+ pass
+ # C2
+ rs = r"64 bytes from {}: icmp_seq=[0-9]+ ttl=[0-9]+ time=\d+\.\d+ ms".format(IP_C1)
+ if re.search(rs, results['VPNClient2_ping_C1']):
+ score += 0.5
+ else:
+ hints.append("ping from VPNClient2 to VPNClient1 is not OK")
+ pass
+ rs = r"64 bytes from {}: icmp_seq=[0-9]+ ttl=[0-9]+ time=\d+\.\d+ ms".format(IP_C3)
+ if re.search(rs, results['VPNClient2_ping_C3']):
+ score += 0.5
+ else:
+ hints.append("ping from VPNClient2 to VPNClient3 is not OK")
+ pass
+ # C3
+ rs = r"64 bytes from {}: icmp_seq=[0-9]+ ttl=[0-9]+ time=\d+\.\d+ ms".format(IP_C1)
+ if re.search(rs, results['VPNClient3_ping_C1']):
+ score += 0.5
+ else:
+ hints.append("ping from VPNClient3 to VPNClient1 is not OK")
+ pass
+ rs = r"64 bytes from {}: icmp_seq=1 ttl=[0-9]+ time=\d+\.\d+ ms".format(IP2_C2)
+ if re.search(rs, results['VPNClient3_ping_C2']):
+ score += 0.5
+ else:
+ hints.append("ping from VPNClient3 to VPNClient2 is not OK")
+ pass
+ #score = int(score)
+
+ # testi za tracetoute
+ # C1
+ rs = r"1 {}".format(IP1_C2)
+ if re.search(rs, results['VPNClient1_traceroute_C3']):
+ rs = r"2 {}".format(IP_C3)
+ if re.search(rs, results['VPNClient1_traceroute_C3']):
+ score += 1
+ else:
+ hints.append("traceroute from VPNClient1 to VPNClient3 is not OK")
+ pass
+ else:
+ hints.append("traceroute from VPNClient1 to VPNClient3 is not OK")
+ pass
+ # C3
+ rs = r"1 {}".format(IP2_C2)
+ if re.search(rs, results['VPNClient3_traceroute_C1']):
+ rs = r"2 {}".format(IP_C1)
+ if re.search(rs, results['VPNClient3_traceroute_C1']):
+ score += 1
+ else:
+ hints.append("traceroute from VPNClient1 to VPNClient3 is not OK")
+ pass
+ else:
+ hints.append("traceroute from VPNClient1 to VPNClient3 is not OK")
+ pass
+ if score > 10 :
+ score -= 1
+ score = int(score)
+ return score, hints
+
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
diff --git a/tasks/openvpn_simple_smb/howtos/en/index.html b/tasks/openvpn_simple_smb/howtos/en/index.html
new file mode 100644
index 0000000..aba834e
--- /dev/null
+++ b/tasks/openvpn_simple_smb/howtos/en/index.html
@@ -0,0 +1,98 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+<strong><h1>OpenVPN and SMB task:</h1></strong>
+<p><strong><h2>Quick task:</h2></strong><br>
+ Connect to VPN with OpenVPN. Enable access to files through NFS and copy them through SMB.</p>
+<p><strong><h2>Instructions:</h2></strong><br>
+ 1. From Directory with images of virtual computers drag twice the picture SimpleArbiterVPN and VPNClient.<br>
+ 2. With VirtualBox (or other programs for virtual computers) create two virtual computers and give them VPNCLient.vdi and SimpleArbiterVPN.vdi as disk for storage.<br>
+ 3. On both set two network interface(NAT and Internal) and run them.<br>
+ 4. On both VM login with username <strong>root</strong> and password <strong>kaboom</strong> .</p>
+<p><h3><u><strong><em>First part: Set up OpenVPN on SimpleArbiterVPN and VPNClient.</em></strong></u></h3>
+<p><h4><u><strong><em>Settings on the server:</em></strong></u></h4>
+ 1. Download packages <strong>uml-utilities</strong> -> to adjust the virtual network interfaces and packet (<strong>openvpn</strong>). example: sudo apt-get install openvpn<br>
+ 2. The new virtual network interface create with <strong>tunctl</strong> and specify IP with <strong>sudo ifconfig tap0 10.P.Q.R netmask 255.255.255.0</strong><br>
+ 3. Then generirate common key (you will share that key with client) with the command: <strong>openvpn --genkey --secret vpnkljuc.key</strong><br>
+ 4. On server set the configuration file tap0.conf, which should contain (split by lines) "dev tap0","proto tcp-server", "secret vpnkljuc.key"<br>
+ 5. Run openvpn with <strong>openvpn --config /some_directory/somewhere/tap0.conf</strong><br/>
+<p><h4><u><strong><em>Settings on the client:</em></strong></u></h4>
+1., 2. steps are the same as the settings on the server<br>
+3. Create configuration file tap0.conf, which should contain (split by lines) "remote IP_OF_YOUR_VPN_SERVR", "dev tap0", "proto tcp-client", "secret vpnkljuc.key"<br>
+4. On OpenVPN server connect to <strong>openvpn --config /some_directory/somewhere/tap0.conf</strong><br/>
+<p>
+
+ <u><strong><em><h3>Second part: Access to imenika /home/test/IME_IMENIKA over NFS</h3></em></strong></u>
+<p><h4><u><strong><em>Client settings:</em></strong></u></h4>
+ 1. Using "sudo apt-get install nfs-kernel-server" we install nfs service<br>
+ 2. Create a directory /home/test/IME_IMENIKA<br/>
+ 3. To /etc/exports add line /home/test/bla IP_client
+ 4. Use sudo exportfs -a to save
+ 5. Restart service using "sudo service nfs-kernel-server start"
+<p><h4><u><strong><em>Client settings:</em></strong></u></h4>
+ 1. Instal client for nfs with command "sudo apt-get install nfs-common"<br/>
+ 2. Create mounting directory "sudo mkdir -p /mnt/nfs/home/test" and mount servers file "sudo mount IP_SERVER:/home/test"<br/>
+ 3. For automatic mounting we add previous commands to /etc/fstab <br/>
+
+<p><h3><u><strong><em>How-to za uporabo kpov-judge za OpenVPN</em></strong></u></h3>
+
+ </font>
+
+<hr>
+<p>
+howto: task_check(results, params):
+ Metoda dobi, kot prvi argument rezultat metode task(...), kot drugi pa
+ rezultat funkcije gen_params().
+
+ Vrne stevilo pridobljenih tock.
+
+
+howto: task(...):
+ Metoda prejme naslednje argumente:
+ - IP naslov VPN streznika
+ - DNS naslov VPN streznika
+ - IP naslov klienta 1
+ - DNS naslov klienta 1
+ - IP naslov klienta 2
+ - DNS naslov klienta 2
+
+ Vrne slovar rezultatov:
+
+ results['SimpleArbiter_is_VPN_set_up']
+ pove ali je VPN streznik nastavljen
+
+ results['SimpleArbiter_is_VPN_running']
+ pove ali je VPN streznik zagnan
+
+ results['SimpleArbiter_ping_C1']
+ ping rezultati (streznik -> klient1)
+
+ results['SimpleArbiter_ping_C2']
+ ping rezultati (streznik -> klient2)
+
+ results['SimpleArbiter_nmap_results']
+ pove ali sta oba klienta povezana na pravi VPN streznik
+
+ results['SimpleArbiter_dir_vpn_contents']
+ kljuc, ce se ta nahaja v ustreznem imeniku
+
+ results['SimpleArbiter_nfs_access_control_list']
+ preveri ce NFS dovoljuje dostop do /home/test/IME_UPORABNIKA
+
+ results['VPNClient1_ping_VPN_server']
+ ping rezultati (klient 1 -> strežnik)
+
+ results['VPNClient2_ping_VPN_server']
+ ping rezultati (klient 2 -> strežnik)
+
+</p>
+
+</body>
+
+</html>
+
+</html>
diff --git a/tasks/openvpn_simple_smb/howtos/si/index.html b/tasks/openvpn_simple_smb/howtos/si/index.html
new file mode 100644
index 0000000..67e1c4e
--- /dev/null
+++ b/tasks/openvpn_simple_smb/howtos/si/index.html
@@ -0,0 +1,95 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+<strong><h1>OpenVPN in SMB vaja: </h1></strong>
+<p><strong><h2>Naloga na hitro: </h2></strong><br>
+ Vzpostavi VPN povezavo z pomočjo OpenVPN. Omogoči dostop do datotek prek NFS in skopiraj datoteke prek SMB.</p>
+<p><strong><h2>Navodila:</h2></strong><br>
+ 1. Iz imenika s slikami virtualnih računalnikov dvakrat povlecite sliki SimpleArbiterVPN ter VPNClient.<br>
+ 2. Z VirtualBoxom (ali ostalim programom za virtualne računalnike) ustvarite dva virtualna računalnika in jim kot disk za shranjevanje podajte VPNCLient.vdi ter SimpleArbiterVPN.vdi.<br>
+ 3. Na obeh nastavite dva omrežna vmesnika (NAT in Internal) in jih zaženite.<br>
+ 4. Na oba VM-a se prijavite z uporabnikom <strong>root</strong> in geslom <strong>kaboom</strong> .</p>
+<p><h3><u><strong><em>Prvi del naloge: Nastavi OpenVPN na SimpleArbiterVPN in VPNClient.</em></strong></u></h3>
+<p><h4><u><strong><em>Nastavitve na strežniku:</em></strong></u></h4>
+ 1. Prenesite pakete <strong>uml-utilities</strong> -> za nastavljanje navideznih omrežnih vmesnikov in paket (<strong>openvpn</strong>). Npr: sudo apt-get install openvpn<br>
+ 2. Nov navidezni omrežni vmesnik kreirate z <strong>tunctl</strong> in mu podate IP z <strong>sudo ifconfig tap0 10.P.Q.R netmask 255.255.255.0</strong><br>
+ 3. Nato generirate skupen ključ(ta ključ boste delili z klientom) z ukazom: <strong>openvpn --genkey --secret vpnkljuc.key</strong><br>
+ 4. Na strežniku še nastavite konfiguracijsko datoteko tap0.conf, ki naj vsebuje (ločeno po vrsticah) "dev tap0","proto tcp-server", "secret vpnkljuc.key"<br>
+ 5. Zaženete openvpn z <strong>openvpn --config /some_directory/somewhere/tap0.conf</strong><br/>
+<p><h4><u><strong><em>Nastavitve na klientu:</em></strong></u></h4>
+1., 2. koraka sta ista kot pri nastavitvah na strežniku<br>
+3. Kreirajte konfiguracijsko datoteko tap0.conf, ki naj vsebuje (ločeno po vrsticah) "remote IP_VAŠEGA_VPN_SERVERJA", "dev tap0", "proto tcp-client", "secret vpnkljuc.key"<br>
+4. Na OpenVPN strežnik se povežete z <strong>openvpn --config /some_directory/somewhere/tap0.conf</strong><br/>
+<p>
+ <u><strong><em><h3>Drugi del naloge: Dostop prek NFS do imenika /home/test/IME_IMENIKA </h3></em></strong></u>
+<p><h4><u><strong><em>Nastavitve na strežniku:</em></strong></u></h4>
+ 1. Z ukazom "sudo apt-get install nfs-kernel-server" namestimo nfs program<br>
+ 2. Uredimo mapo exports "sudo nano /etc/exports" in kreiramo direktorij /home/test/IME_IMENIKA<br/>
+ 3. V datoteko exports dodamo /home/test/bla IP_klienta
+ 4. Share shranimo z sudo exportfs -a
+ 5. NFS strežnik štartamo z "sudo service nfs-kernel-server start"
+<p><h4><u><strong><em>Nastavitve na klientu:</em></strong></u></h4>
+ 1. Z ukazom "sudo apt-get install nfs-common" namestimo programček nfs-common, da lahko kasneje pripnemo share<br/>
+ 2. Na klientu moramo urediti še mount tega direktorija: "sudo mkdir -p /mnt/nfs/home/test" in "sudo mount IP_SERVERJA:/home/test"<br/>
+ 3. Za avtomatski mount ob ponovnem zagonu, dodamo prejšnje ukaze v datoteko /etc/fstab <br/>
+
+<p><h3><u><strong><em>How-to za uporabo kpov-judge za OpenVPN</em></strong></u></h3>
+
+ </font>
+
+<hr>
+<p>
+howto: task_check(results, params):
+ Metoda dobi, kot prvi argument rezultat metode task(...), kot drugi pa
+ rezultat funkcije gen_params().
+
+ Vrne stevilo pridobljenih tock.
+
+
+howto: task(...):
+ Metoda prejme naslednje argumente:
+ - IP naslov VPN streznika
+ - DNS naslov VPN streznika
+ - IP naslov klienta 1
+ - DNS naslov klienta 1
+ - IP naslov klienta 2
+ - DNS naslov klienta 2
+
+ Vrne slovar rezultatov:
+
+ results['SimpleArbiter_is_VPN_set_up']
+ pove ali je VPN streznik nastavljen
+
+ results['SimpleArbiter_is_VPN_running']
+ pove ali je VPN streznik zagnan
+
+ results['SimpleArbiter_ping_C1']
+ ping rezultati (streznik -> klient1)
+
+ results['SimpleArbiter_ping_C2']
+ ping rezultati (streznik -> klient2)
+
+ results['SimpleArbiter_nmap_results']
+ pove ali sta oba klienta povezana na pravi VPN streznik
+
+ results['SimpleArbiter_dir_vpn_contents']
+ kljuc, ce se ta nahaja v ustreznem imeniku
+
+ results['SimpleArbiter_nfs_access_control_list']
+ preveri ce NFS dovoljuje dostop do /home/test/IME_UPORABNIKA
+
+ results['VPNClient1_ping_VPN_server']
+ ping rezultati (klient 1 -> strežnik)
+
+ results['VPNClient2_ping_VPN_server']
+ ping rezultati (klient 2 -> strežnik)
+
+</p>
+
+</body>
+
+</html>
diff --git a/tasks/openvpn_simple_smb/task.py b/tasks/openvpn_simple_smb/task.py
new file mode 100644
index 0000000..5d7c22f
--- /dev/null
+++ b/tasks/openvpn_simple_smb/task.py
@@ -0,0 +1,261 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si': '''\
+<p>
+Postavi dva navidezna računalnika: <em>SimpleArbiter</em> in <em>VPNClient1</em>. Poskrbite, da bosta povezana med seboj in v internet. Na <em>VPNClient1</em> namestite OpenVPN in program za nadzor nad virtualnimi napravami (s katerim kreirate napravo <code>tap</code>).
+
+<p>
+Na strežniku <em>SimpleArbiter</em> že teče strežnik in uporablja skrivnost, ki jo najdete tudi na <em>VPNClient1</em> v domačem imeniku uporabnika <code>student</code>. Na <em>VPNClient1</em> vzpostavite VPN tako, da napišete primerno datoteko z nastavitvami. Računalniku <em>VPNClient1</em> na navideznem lokalnem omrežju nastavite naslov
+<code>{{IP_VPNClient1}}</code>.
+
+<p>
+Nato poskrbite, da bo na <em>VPNClient1</em> na navideznem omrežju prek NFS omogočen
+dostop do imenika <code>/home/test/{{DIRNAME}}</code>. V ta imenik skopirajte datoteke, ki so prek SMB dostopne na <em>SimpleArbiter</em>.
+''',
+ 'en': '''\
+<p>
+Setup two virtual machines: <em>SimpleArbiter</em> and <em>VPNClient1</em>. Set the client's network up so that it has access to the internal network and the internet. On <em>VPNClient1</em>, install OpenVPN and a program for supervising virtual devices
+(which you will use to create a <code>tap</code> device). On the VPN, set the IP for
+<em>VPNClient1</em> to <code>{{IP_VPNClient1}}</code>.
+
+<p>
+An OpenVPN server is already running on <em>SimpleArbiter</em>. Use the secret
+available on <em>VPNClient1</em> in the home directory of user <code>student</code> to connect to the VPN server on <em>SimpleArbiter</em>. To do that, you will have to write your
+own OpenVPN configuration file.
+
+<p>
+After you have set up the VPN, make the directory <code>/home/test/{{DIRNAME}}</code> on <em>VPNClient1</em> available over NFS from <em>SimpleArbiter</em> over
+your VPN. Copy files that are available from <em>SimpleArbiter</em> over SMB to <code>/home/test/{{DIRNAME}}</code>.
+'''
+}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ {
+ 'name': 'simpleArbiterDhcpGWVPN',
+ },
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'test-net'
+ },
+ {
+ 'network': 'net1'
+ }
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'VPNClient1': {
+ 'disks': [
+ { 'name': 'student-VPNClient1',
+ },
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1'
+ }
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+}
+
+networks = {
+ 'test-net': {
+ 'public': True
+ },
+ # Used for the VPN tunnel
+ 'net1': {
+ 'public': False
+ }
+}
+
+#Tukaj sem generiral tri parametre, prosil bi če se upoštevajo pri Tasku.
+params_meta = {
+ 'IP_SimpleArbiterVPN': {'descriptions':{'si':'IP za SimpleArbiter na VPN'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_VPNClient1': {'descriptions':{'si':'IP klienta na VPN'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_LANClient1': {'descriptions':{'si':'IP klienta na LAN'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
+ 'DIRNAME': {'descriptions':{'si':'Imenik, dostopen prek NFS'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'secret_random_seed': {'descriptions':{'si':'Seme za skrivnost'}, 'w': False, 'public': False, 'type': None, 'generated': True},
+}
+
+def task(IP_SimpleArbiterVPN, IP_VPNClient1, IP_LANClient1, DIRNAME):
+ import collections
+ from pexpect import pxssh # Used to set up an SSH connection to a remote machine
+ import pexpect # Allows the script to spawn a child application and control it as if a human were typing commands
+
+ # The necessary things we need to check if the task was performed correctly
+ results = collections.defaultdict(str)
+
+ # VPNClient1
+ sC1 = pxssh.pxssh(encoding='utf-8')
+ sC1.login(IP_LANClient1, 'student', 'vaje')
+
+ # sA
+ results['SimpleArbiter_ifconfig'] = pexpect.run(
+ 'ifconfig -a', encoding='utf-8', env={'PATH': '/bin:/sbin'})
+ results['SimpleArbiter_route'] = pexpect.run(
+ 'route -n', encoding='utf-8', env={'PATH': '/bin:/sbin'})
+
+ # Pings each of the clients
+ # 10.8.0.6 and 10.8.0.10 are the first two default addresses distributed by OpenVPN
+ # Will output everything ping outputs (set to ping 3 times)
+ results['SimpleArbiter_ping_C1'] = pexpect.run(
+ 'ping -c 3 {}'.format(IP_VPNClient1), encoding='utf-8')
+ results['SimpleArbiter_traceroute'] = pexpect.run(
+ 'traceroute {}'.format(IP_VPNClient1), encoding='utf-8')
+ sC1.sendline('cat /etc/exports')
+ sC1.prompt()
+ output = sC1.before
+ results['VPNClient1_nfs_access_control_list'] = output
+ results['SimpleArbiter_mount'] = pexpect.run(
+ 'sudo mount {}:/home/test/{} /mnt'.format(IP_VPNClient1, DIRNAME), encoding='utf-8')
+ results['SimpleArbiter_mount_result'] = pexpect.run(
+ 'sudo mount', encoding='utf-8')
+ results['SimpleArbiter_ls'] = pexpect.run(
+ 'ls /mnt', encoding='utf-8')
+ pexpect.run(
+ 'sudo umount /mnt', encoding='utf-8')
+
+ # Ping the VPN server
+ sC1.sendline('ping -c 3 {0}'.format( IP_SimpleArbiterVPN ))
+ sC1.prompt()
+ results['VPNClient1_ping_VPN_server'] = sC1.before
+
+ sC1.sendline('/sbin/ifconfig -a')
+ sC1.prompt()
+ results['VPNClient1_ifconfig'] = sC1.before
+
+ sC1.sendline('ps xa')
+ sC1.prompt()
+ results['VPNClient1_ps'] = sC1.before
+ sC1.logout()
+
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ #Tukaj sem generiral te tri parametre (ime skupne skrivnosti je heidi )
+ #(ime imenika kjer naj bo shranjena skupna skrivnost naj bo openvpn)
+ #(HASH bo naključno generiran niz iz user_id s katerim se bo preverjalo plagiatorstvo)
+ import random
+ r = random.Random(user_id)
+ net = kpov_util.IPv4_subnet_gen(r, '10.168.0.0/16', 24)
+ params['IP_VPNClient1'], params['IP_SimpleArbiterVPN'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DIRNAME'] = kpov_util.fname_gen(r, extension=False)
+ params['secret_random_seed']=str(r.random())
+ return params
+
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+
+ IP_SA = params['IP_SimpleArbiterVPN'].replace('.', '\.')
+ IP_C1 = params['IP_VPNClient1'].replace('.', '\.')
+ rs = r"tap0: flags=.* mtu 1500\r\n +inet {}".format(IP_SA)
+ if re.search(rs,
+ results['SimpleArbiter_ifconfig']):
+ score += 1
+ else:
+ hints.append("ifconfig on SimpleArbiter not OK")
+
+ if re.search(
+ "PING.*\r\n64 bytes from {}: icmp_seq=[0-9]+ ttl=64 time=[0-9.]* ms".format(IP_C1),
+ results['SimpleArbiter_ping_C1']):
+ score += 1
+ else:
+ hints.append("ping from server not OK")
+ rs = "1 +{0} \({0}\)".format(IP_C1)
+ if re.search(rs, results['SimpleArbiter_traceroute']):
+ score += 1
+ else:
+ hints.append("traceroute not OK")
+ if results['VPNClient1_nfs_access_control_list'].find(
+ '/home/test/' + params['DIRNAME'] + ' ') >= 0:
+ score += 1
+ if results['SimpleArbiter_mount_result'].find(
+ '{}:/home/test/{} on /mnt type nfs'.format(
+ params['IP_VPNClient1'], params['DIRNAME'])):
+ score += 1
+ else:
+ hints.append("mount not OK")
+
+ # get r into the correct state
+ r = random.Random(params['secret_random_seed'])
+ s = "\n".join(["".join([r.choice("0123456789abcdef") for i in range(32)])
+ for i in range(16)])
+ keyfile = kpov_util.fname_gen(r, extension=False)
+
+ # now check the filenames
+ fnames_ok = True
+ for i in range(3):
+ fname = kpov_util.fname_gen(r, False)
+ foo = kpov_util.fortune(r, 4096)
+ pos = results['SimpleArbiter_ls'].find(fname + '.txt')
+ fnames_ok = fnames_ok and pos >= 0
+ if fnames_ok:
+ score += 2
+ else:
+ hints.append("shared filenames not OK:")
+
+ # Ping the VPN server
+ if re.search(
+ "PING.*\r\n64 bytes from {}: icmp_seq=[0-9]+ ttl=64 time=[0-9.]* ms".format(IP_SA),
+ results['VPNClient1_ping_VPN_server']):
+ score += 1
+ else:
+ hints.append("ping from client not OK")
+
+ rs = r"tap0: flags=.* mtu 1500\r\n +inet {}".format(IP_C1)
+ if re.search(rs, results['VPNClient1_ifconfig']):
+ score += 1
+ else:
+ hints.append("ifconfig on VPNClient1 not OK")
+
+ if results['VPNClient1_ps'].find('openvpn') > 0:
+ score += 1
+ else:
+ hints.append("openvpn not found running on VPNClient")
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ #guestmount -a d -m /dev/VG/LV -m /dev/sda1:/boot --ro /mnt
+ #asistent je pocasnela :)
+ import random
+ r = random.Random(task_params['secret_random_seed'])
+ s = "\n".join([
+ "".join([r.choice("0123456789abcdef") for i in range(32)])
+ for i in range(16)])
+ s = """#
+# 2048 bit OpenVPN static key
+#
+-----BEGIN OpenVPN Static key V1-----
+{}
+-----END OpenVPN Static key V1-----
+""".format(s)
+ keyfile = kpov_util.fname_gen(r, extension=False) + ".key"
+ templates['simpleArbiterDhcpGWVPN'].write("/etc/openvpn/secret.key", s)
+ netaddr_s = """auto tap0
+iface tap0 inet static
+ openvpn server
+ pre-up tunctl -t tap0
+ address {}
+ netmask 255.255.255.0
+""".format(task_params['IP_SimpleArbiterVPN'])
+ templates['simpleArbiterDhcpGWVPN'].write_append("/etc/network/interfaces", netaddr_s)
+ for i in range(3):
+ fname = kpov_util.fname_gen(r, False)
+ templates['simpleArbiterDhcpGWVPN'].write(
+ "/srv/smb/" + fname + '.txt',
+ kpov_util.fortune(r, 4096))
+ write_default_config(templates['simpleArbiterDhcpGWVPN'], global_params)
+ templates['student-VPNClient1'].write("/home/student/" + keyfile, s)
+ # uid, gid (student = )
+ templates['student-VPNClient1'].chown(1000, 1000, "/home/student/" + keyfile)
+
+ write_default_config(templates['simpleArbiterDhcpGWVPN'], global_params)
diff --git a/tasks/openwrt/task.py b/tasks/openwrt/task.py
new file mode 100644
index 0000000..8872989
--- /dev/null
+++ b/tasks/openwrt/task.py
@@ -0,0 +1,103 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavi dva navidezna računalnika - simpleArbiter z diska SimpleArbiter ter
+OpenWRT z diska OpenWRT. Na disku OpenWRT je nameščena distribucija OpenWRT.
+Nastavi OpenWRT tako, da bo imel dva omrežna vmesnika - en naj bo povezan na Internet,
+drugo na omrežje, na katerem bo SimpleArbiter. Na SimpleArbiter preberi naslov omrežja
+med OpenWrt in SimpleArbiter ter njuna naslova.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions': {'si': 'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
diff --git a/tasks/public_ip_ssh/task.py b/tasks/public_ip_ssh/task.py
new file mode 100644
index 0000000..8dcb858
--- /dev/null
+++ b/tasks/public_ip_ssh/task.py
@@ -0,0 +1,52 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Ustvari dva navidezna računalnika. Za disk enega (imenujmo ga SimpleArbiter) uporabite
+sliko diska Test. Na drugega (imenujmo ga A) namesti poljubno Linux distribucijo. Na SimpleArbiter
+preberi uporabniško ime in geslo uporabnika, ki ga moraš ustvariti na A. Poskrbi, da se bo novoustvarjeni
+uporabnik s svojim geslom lahko na A prijavil z Interneta.</pre>
+"""
+}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks':[
+ { 'name': 'simpleArbiter' }],
+ 'network_interfaces':[{'network':'net1'}],
+ },
+ 'A': {
+ 'disks':[],
+ 'network_interfaces':[{'network':'net2'}],
+ }
+
+}
+
+networks = { 'net1': {'public': True}, 'net2': {'public': True} }
+
+params_meta = {
+ 'peer_ip': {'descriptions': {'si': 'Naslov ssh strežnika'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'peer_user': {'descriptions': {'si': 'ime uporabnika'}, 'w': False, 'public': True, 'type': 'username', 'generated': True},
+ 'peer_passwd': {'descriptions': {'si': 'geslo uporabnika'}, 'w': False, 'public': True, 'type': 'password', 'generated': True},
+}
+
+def task(peer_ip, peer_user, peer_passwd):
+ return dict()
+
+def gen_params(user_id, params_meta):
+ return kpov_util.default_gen(user_id, params_meta)
+
+def task_check(results, params):
+ from pexpect import pxssh
+ ip, user, passwd = params['peer_ip'], params['peer_user'], params['peer_passwd']
+ results = {}
+ try:
+ s = pxssh.pxssh(encoding='utf-8')
+ s.login(ip, user, passwd)
+ s.logout()
+ return 10, []
+ except Exception as ex:
+ return 0, [str(ex)]
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiter'], global_params)
diff --git a/tasks/public_ssh_motd_http/task.py b/tasks/public_ssh_motd_http/task.py
new file mode 100644
index 0000000..bd48d77
--- /dev/null
+++ b/tasks/public_ssh_motd_http/task.py
@@ -0,0 +1,105 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Na internet postavi računalnik, ki bo dostopen prek ssh in http.
+Poskrbi, da bo na računalniku ustvarjen uporabnik test z geslom test. Ob prijavi naj se
+uporabniku v MOTD izpiše (le) zgodbica ali pesmica, ki vam je všeč, dolžine vsaj 50 znakov.
+Ista zgodbica ali pesmica naj se na strežniku izpiše, če se na strežnik kdorkoli poveže prek
+http.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions': {'si': 'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+# d = templates['simpleArbiterDhcp']
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
+
diff --git a/tasks/radius_multiple_realms/task.py b/tasks/radius_multiple_realms/task.py
new file mode 100644
index 0000000..0067f46
--- /dev/null
+++ b/tasks/radius_multiple_realms/task.py
@@ -0,0 +1,110 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavi tri navidezne računalnike - SimpleArbiter z diska simpleArbiterDhcp,
+RadiusA ter RadiusB. Na simpleArbiterDhcp preberi imeni domen DOMENA_A ter DOMENA_B,
+uporabniški imeni USER_A in USER_B, gesli PASSWORD_A in PASSWORD_B ter skrivnosti
+SECRET_A in SECRET_B. Poskrbi, da se bo lahko radius klient s SimpleArbiter povezal
+na RadiusA s skrivnostjo SECRET_A ter na RadiusB s skrivnostjo SECRET_B. Poskrbi še,
+da bo v nastavitvah OpenRadius na RadiusA obstajal uporabnik USER_A z geslom PASSWORD_A ter
+na RadiusB uporabnik USER_B z geslom PASSWORD_B.
+
+Poskrbi, da bo strežnik RadiusA odgovarjal na zahtevke za avtentikacijo uporabnikov na domeni DOMENA_A,
+zahtevke za uporabnike na domeni DOMENA_B pa bo preposlal naprej na RadiusB. RadiusB naj odgovarja na
+zahtevke za uporabnike na domeni DOMENA_B, zahtevke za uporabnike na DOMENA_A pa naj preprosto zavrže.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions': {'si': 'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
+
diff --git a/tasks/radius_mysql_pam/howtos/en/index.html b/tasks/radius_mysql_pam/howtos/en/index.html
new file mode 100644
index 0000000..ac53a1f
--- /dev/null
+++ b/tasks/radius_mysql_pam/howtos/en/index.html
@@ -0,0 +1,34 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+<strong><h1>Radius mysql:</h1></strong>
+<p><strong><h2>Quick how to:</h2></strong><br>
+ Setup the OpenRadius server and add users. Use MySql as the database.</p>
+<strong><h2>Instructions:</h2></strong>
+ <ol>
+ <li>Create two virtual machines - SimpleArbiter (use the simpleArbiterDhcp.vdi disk) and RadiusServer. Discs for virtual machines are located on polz.si/media/uploads/kpov/virtualke.</li>
+ <li>Create another two virtual machines using the disks VPNCLient.vdi and SimpleArbiterVPN.vdi.</li>
+ <li>Setup both VMs so that they use two network adapters - NAT and Internal network.</li>
+ <li>Login with the username <strong>student</strong> and password <strong>student</strong> on both VMs.</li>
+ </ol>
+
+<h3><u><strong><em>Part one: Setup OpenRadius.</em></strong></u></h3>
+ <ol>
+ <li>Install OpenRadius on the RadiusServer VM (configuration files are: /etc/openradius/configuration and /etc/openradius/behaviour)</li>
+ <li>Add a user and assign him a shared secret. This should be configured in the /etc/openradius/configuration file. (More info: <a href = "http://sites.e-advies.nl/openradius/doc-using-openradius.html"> http://sites.e-advies.nl/openradius/doc-using-openradius.html </a>)</li>
+ <li>Create a connection from SimpleArbiter to RadiusServer using the secret you configured.</strong></li>
+ </ol>
+<u><strong><em><h3>Part two: Install and setup a MySQL database on RadiusServer</h3></em></strong></u>
+ <ol>
+ <li>OpenRadius can use the module RadSQL to store users in database.</li>
+ <li>Setup a MySQL server: sudo apt-get install mysql-server.</li>
+ <li>Connect to the MySQL server: mysql -u root -p.</li>
+ <li>Create a database: CREATE DATABASE <database-name>. Create a table <strong>users</strong> with columns <strong>username</strong> and <strong>password</strong>.</li>
+ </ol>
+</body>
+
+</html>
diff --git a/tasks/radius_mysql_pam/howtos/si/index.html b/tasks/radius_mysql_pam/howtos/si/index.html
new file mode 100644
index 0000000..612cce9
--- /dev/null
+++ b/tasks/radius_mysql_pam/howtos/si/index.html
@@ -0,0 +1,40 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+<strong><h1>Radius mysql:</h1></strong>
+<p><strong><h2>Naloga na hitro:</h2></strong><br>
+ Postaviti je treba RADIUS strežnik in podatkovno bazo.<br>
+ Za RADIUS strežnik uporabite FreeRADIUS, za podatkovno bazo pa MySQL.
+</p>
+<p><strong><h2>Navodila:</h2></strong><br>
+ 1. Ustvarite dva navidezna računalnika z imenom SimpleArbiter in RadiusServer.<br>
+ Za SimpleArbiter uporabite simpleArbiterDhcp, za RadiusServer pa lahko uporabite poljubno virtualko.<br>
+ ( virtualke dobiš na polz.si/media/uploads/kpov/virtualke)<br>
+ 2. Z VirtualBoxom (ali ostalim programom za virtualne računalnike) ustvarite dva virtualna računalnika in jim kot disk za shranjevanje podajte simpleArbiterDhcp.vdi ter base-student-console-2014.vdi.<br>
+ 3. Na obeh nastavite dva omrežna vmesnika (NAT in Internal) in jih zaženite.<br>
+ 4. Na oba VM-a se prijavite z uporabnikom <strong>student</strong> in geslom <strong>vaje</strong> .</p>
+<p><h3><u><strong><em>Prvi del naloge: Postavi OpenRadius.</em></strong></u></h3>
+ 1. Namesti FreeRadius na virtualki RadiusServer z ukazom "sudo apt-get install freeradius".<br>
+ ( pomembni sta dve konfiguracijski datoteki /etc/openradius/configuration in /etc/openradius/behaviour<br>
+ 2. Dodaj uporabnika in mu dodaj skupno skrivnost v /etc/openradius/configuration datoteko (več o dodajanju lahko izveš na: "http://sites.e-advies.nl/openradius/doc-using-openradius.html" <br>
+ 3. Nato se z to skrivnostjo povežete iz SimpleArbiter na RadiusServer</strong><br>
+
+ Namestimo freeradius z ukazom apt-get install freeradius-mysql
+ V datoteku /etc/freeradius/client.conf spremenimo skrivnost (secret)
+ Nato pa v datoteki /etc/freeradius/users dodamo uporabnika
+
+
+<u><strong><em><h3>Drugi del naloge: Namestitev in vzpostavitev baze MySQL na RadiusServer </h3></em></strong></u>
+ 1. Pri OpenRadius-u imamo modul RadSQL, s katerim lahko vzpostavimo hranjenje uporabnikov v bazi<br>
+ 2. Namestimo MySQL server z ukazom "sudo apt-get install mysql-server"<br/>
+ 3. VNato se prijavimo v Mysql server z ukazom mysql -u root -p <br/>
+ 4. Bazo ustvarimo z ukazom primer:
+ CREATE DATABASE kwhbRgJY;
+ GRANT ALL ON kwhbRgJY.* To MajaNovak80@localhost IDENTIFIED BY "y06gmo2Z";
+</body>
+
+</html>
diff --git a/tasks/radius_mysql_pam/task.py b/tasks/radius_mysql_pam/task.py
new file mode 100644
index 0000000..5051bb4
--- /dev/null
+++ b/tasks/radius_mysql_pam/task.py
@@ -0,0 +1,212 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si': '''\
+<p>
+Ustvari dva navidezna računalnika: <em>SimpleArbiter</em> in <em>RadiusServer</em>. Na <em>RadiusServer</em> namesti FreeRadius ter MySQL.
+
+<p>
+Ustvari podatkovno bazo MySQL z imenom <code>{{MYSQL_DB_NAME}}</code>. Ustvari uporabnika za MySQL z imenom <code>{{MYSQL_ADMIN_USER}}</code> in geslom <code>{{MYSQL_ADMIN_PASSWORD}}</code>, ki naj ima poln dostop do te baze. Prijava za tega uporabnika mora biti omogočena tudi s <em>SimpleArbiter</em>.
+
+<p>
+Nastavi FreeRadius tako, da bo podatke o uporabnikih in geslih pobiral iz baze MySQL z imenom <code>{{MYSQL_DB_NAME}}</code>. Podatkovna shema (imena tabel) naj ostane
+privzeta.
+
+<p>
+Dostop do strežnika Radius na <em>RadiusServer</em> s <em>SimpleArbiter</em> naj bo mogoč ob uporabi skrivnosti <code>{{RADIUS_SECRET}}</code>.
+
+<p>
+V bazi ustvari vnos, ki bo omogočil, da se na <em>RadiusServer</em> s pomočjo protokola Radius avtenticira uporabnik <code>{{RADIUS_USERNAME}}</code> z geslom <code>{{RADIUS_PASSWORD}}</code>.
+
+<p>
+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 <code>/etc/shadow</code> oziroma <code>/etc/password</code>.
+''',
+ 'en': '''\
+<p>
+Create two virtual machines: <em>SimpleArbiter</em> and <em>RadiusServer</em>. On <em>RadiusServer</em>, install FreeRadius and MySQL.
+
+<p>
+Create a MySQL database named <code>{{MYSQL_DB_NAME}}</code>. Create a mysql user with the username <code>{{MYSQL_ADMIN_USER}}</code> and password <code>{{MYSQL_ADMIN_PASSWORD}}</code>. Make sure this user can access the database from <em>SimpleArbiter</em> and has administrative rights over the <code>{{MYSQL_DB_NAME}}</code> database.
+
+<p>
+Set up FreeRadius so that the data about users and passwords is stored in the MySQL database. Keep the default schema (table names).
+
+<p>
+Make the Radius server on <em>RadiusServer</em> accessible from <em>SimpleArbiter</em> using <code>{{RADIUS_SECRET}}</code> as the secret.
+
+<p>
+Create an entry in the database which will enable a user with the username <code>{{RADIUS_USERNAME}}</code> to authenticate themself against the Radius server using the password <code>{{RADIUS_PASSWORD}}</code>.
+
+<p>
+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 <code>/etc/shadow</code>
+and/or <code>/etc/password</code>.
+''',
+}
+
+#KABOOM
+
+computers = {
+ 'RadiusServer': {
+ 'disks': [
+ { 'name': 'student-RadiusServer',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGW',
+ },
+ ],
+ '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', 'en': 'RadiusServer IP address'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'RADIUS_SECRET':{'descriptions': {'si': 'Skrivnost RADIUS', 'en': 'RADIUS secret'}, 'w': False, 'public':True, 'type': 'password', 'generated': True},
+ 'RADIUS_USERNAME': {'descriptions': {'si': 'Uporabniško ime', 'en': 'Username'}, 'w': True, 'public':True, 'type': 'username', 'generated': False},
+ 'RADIUS_PASSWORD': {'descriptions': {'si': 'Geslo uporabnika', 'en': 'Password'}, 'w': False, 'public':True, 'type': None, 'generated': True},
+ 'MYSQL_DB_NAME': {'descriptions': {'si': 'Ime baze v mysql', 'en': 'Database name'}, 'w': False, 'public':True, 'type': None, 'generated': True},
+ 'MYSQL_ADMIN_USER':{'descriptions': {'si': 'Uporabniško ime za dostop do MySQL', 'en': 'MySQL username'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
+ 'MYSQL_ADMIN_PASSWORD': {'descriptions': {'si': 'Geslo za dostop do MySQL', 'en': 'MySQL password'}, 'w': True, 'public':True, 'type': 'password', 'generated': True},
+ 'MYSQL_SEED':{'descriptions': {'si': 'seed', 'en': '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 collections
+ import random
+ import pexpect
+
+ r = random.Random(MYSQL_SEED)
+ MYSQL_TEST_USER = kpov_util.username_gen(r)
+ MYSQL_TEST_PASSWORD = kpov_util.alnum_gen(r, 7)
+ RADIUS_NEW_PASSWORD = kpov_util.alnum_gen(r, 7)
+
+ results = collections.defaultdict(str)
+
+ # Testiranje radius strež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))
+
+ mysql.sendline("UPDATE radcheck SET value='{RADIUS_NEW_PASSWORD}' where UserName='{RADIUS_USERNAME}' and Attribute='Cleartext-Password';".format(**locals()))
+
+ results.update(kpov_util.ssh_test(IP_RS, RADIUS_USERNAME, RADIUS_NEW_PASSWORD))
+
+ 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');
+ # TODO 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_util.alnum_gen(r, 8)
+ params['RADIUS_PASSWORD'] = kpov_util.alnum_gen(r, 8)
+ params['RADIUS_USERNAME'] = kpov_util.username_gen(r)
+ params['MYSQL_ADMIN_USER'] = kpov_util.alnum_gen(r, 6)
+ params['MYSQL_ADMIN_PASSWORD'] = kpov_util.alnum_gen(r, 6)
+ params['MYSQL_DB_NAME'] = kpov_util.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_util.username_gen(r)
+ MYSQL_TEST_PASSWORD = kpov_util.alnum_gen(r, 7)
+ RADIUS_NEW_PASSWORD = kpov_util.alnum_gen(r, 7)
+ s = r"Sent Access-Request Id [0-9]+ from ([0-9]|\.)+:[0-9]+ to {IP_RS}:1812 length [0-9]+\r\n\tUser-Name = \"{RADIUS_USERNAME}\"\r\n\tUser-Password = \"{RADIUS_PASSWORD}\".*Access-Accept Id [0-9]+ from {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:
+ hints.append('radtest connect output incorrect:' + results['Test_RadiusServer'])
+ 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:
+ hints.append("mysql connection string incorrect")
+ 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:
+ hints.append('mysql table information string incorrect')
+ 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:
+ hints.append('mysql user entry in table check failed')
+ print((results['select_from_users'], ))
+
+ s = r"Sent Access-Request Id [0-9]+ from ([0-9]|\.)+:[0-9]+ to {0}:1812 length [0-9]+\r\n\tUser-Name = \"{1}\"\r\n\tUser-Password = \"{2}\".*Access-Accept Id [0-9]+ from {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:
+ hints.append('radtest output incorrect:' + results['radtest_OK'])
+ print((s, results['radtest_OK']))
+
+ s = r"Sent Access-Request Id [0-9]+ from ([0-9]|\.)+:[0-9]+ to {0}:1812 length [0-9]+\r\n\tUser-Name = \"{1}\"\r\n\tUser-Password = \"Flügzeug\".*Access-Reject Id [0-9]+ from {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:
+ hints.append('radtest negative output incorrect: ' + results['radtest_NOK'])
+ print((results['radtest_NOK'], s))
+ s = "{RADIUS_USERNAME}@.*:".format(**params)
+ if re.search(s, results['motd'], flags=re.DOTALL):
+ # print "login_test OK"
+ score += 1
+ else:
+ hints.append('login test failed')
+ print((results['login_test'],s))
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcpGW'], global_params)
diff --git a/tasks/rdate_64bit/task.py b/tasks/rdate_64bit/task.py
new file mode 100644
index 0000000..9f90014
--- /dev/null
+++ b/tasks/rdate_64bit/task.py
@@ -0,0 +1,104 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavi dva navidezna računalnika - SimpleArbiter z diska simpleArbiterDhcp ter
+RdateServer. Na RdateServer postavi strežnik, ki bo poslušal na vratih VRATA_X.
+Vsakič, ko se na vrata poveže klient, naj strežnik pošlje število sekund od DATUM_X.
+Število naj bo kodirano kot 64-bitno predznačeno število s tankim koncem.
+
+VRATA_X in DATUM_X preberi na SimpleArbiter.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions':{'si':'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions':{'si':'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions':{'si':'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions':{'si':'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
diff --git a/tasks/rename_grep_network/task.py b/tasks/rename_grep_network/task.py
new file mode 100644
index 0000000..4d81313
--- /dev/null
+++ b/tasks/rename_grep_network/task.py
@@ -0,0 +1,282 @@
+# 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': """
+<pre>Ustvari dva navidezna računalnika s slikama diskov
+- SimpleArbiterExam s sliko diska simpleArbiterDhcp in
+SmallStudent s slikama diska student-entrance3
+in smallstudent-personal.
+
+Drugi razdelek na sliki smallstudent-personal priklopi na imenik {mntdir}
+
+Na SimpleArbiterExam se lahko prijaviš z uporabniškim imenom tester in geslom test.
+Na SmallStudentExam se lahko prijaviš kot root z geslom kaboom.
+
+Poskrbi, da bo SmallStudent s SimpleArbiter dostopen na naslovu {testip}.
+
+Na SmallStudent ustvari uporabnika {testuser} z geslom {passwd}.
+
+Na smallstudent-personal je nekje skrita
+datoteka, ki vsebuje niz {magicstr}.
+Skopiraj jo v domači imenik {testuser} in preimenuj tako, da vse znake 'O' v imenu zamenjaš z 'I'.
+Pazi, da nobena druga datoteka v domačem imeniku v svojem imenu ne bo vsebovala "I".
+
+Poskrbi, da bo lastnik {testuser}, skupina pa naj ostane nespremenjena.
+Brati naj jo ima pravico samo lastnik, pisati lastnik in skupina, poganjati nihče.</pre>
+""",
+ 'en': '''
+''',
+}
+
+instructions = {'si': 'Potrpite.', 'en': 'Have patience.'}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ {
+ 'name': 'simpleArbiterEntrance',
+ },
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net1',
+ },
+ {
+ 'network': 'net2',
+ },
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False,
+ },
+ 'SmallStudent': {
+ 'disks': [
+ {
+ 'name': 'student-entrance4',
+ # 'parts': [{'dev': 'sda1', 'path': '/'}],
+ },
+ {
+ 'name': 'smallstudent-personal',
+ 'parts': [{'dev': 'sdb1', 'path': '/media'}, {'dev': 'sdb2', 'path': '/mnt'}]
+ }
+ ],
+ 'network_interfaces': [
+ {
+ 'network': 'net2',
+ },
+ ],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False,
+ }
+}
+
+networks = {
+ 'net1': {
+ 'public': True,
+ },
+ 'net2': {
+ 'public': False,
+ }
+}
+
+params_meta = {
+ 'testip': {
+ 'descriptions': {
+ 'si': 'IP SmallStudent',
+ 'en': 'IP SmallStudent',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'IP',
+ 'generated': True,
+ },
+ 'testuser': {
+ 'descriptions': {
+ 'si': 'Uporabnik na SmallStudent',
+ 'en': 'Username on SmallStudent',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'username',
+ 'generated': True,
+ },
+ 'passwd': {
+ 'descriptions': {
+ 'si': 'Geslo na SmallStudent',
+ 'en': 'Password on SmallStudent',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': None,
+ 'generated': True,
+
+ },
+ 'mntdir': {
+ 'descriptions': {
+ 'si': 'imenik za priklop diska',
+ 'en': 'mountpoint',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': 'dirname',
+ 'generated': True,
+ },
+ 'magicstr' : {
+ 'descriptions': {
+ 'si': 'Niz v iskani datoteki',
+ 'en': 'String in the file you need to find',
+ },
+ 'w': False,
+ 'public': True,
+ 'type': None,
+ 'generated': True,
+
+ },
+ 'rndseed': {
+ 'descriptions': {
+ 'si': 'random seed za skrito datoteko',
+ 'en': 'random seed for hiding the file',
+ },
+ 'w': False,
+ 'public': False,
+ 'type': None,
+ 'generated': True,
+ },
+}
+
+def task(testip, testuser, passwd, mntdir, magicstr):
+ return kpov_util.ssh_test(testip, testuser, passwd, (
+ ('home_ls', 'ls ~/'),
+ ('dst_file_contents', 'cat ~/*I*.txt'),
+ ('dst_ls', 'ls -l ~/*I*.txt'),
+ ('mnt', 'mount'),
+ ))
+
+def gen_params(user_id, params_meta):
+ import random
+ params = dict()
+ r = random.Random(user_id)
+ params['testip'] = kpov_util.IPv4_addr_gen(r,
+ network = '10.94.80.0/19', n_generated=1)[0]
+ params['testuser'] = kpov_util.default_generators['username'](r)
+ params['passwd'] = kpov_util.alnum_gen(r, 8)
+ params['magicstr'] = "".join([r.choice("qwerztlpoQWERTPOL") for i in range(10)])
+ params['mntdir'] = "/" + kpov_util.default_generators['filename'](r)
+ params['rndseed'] = kpov_util.alnum_gen(r, 8)
+ return params
+
+
+def task_check(results, params):
+ import os
+ import re
+ hints = []
+ score = 0
+ if results['ssh'] is not True:
+ hints += ['ssh failed: ' + results['ssh']]
+ hidden_contents = params['magicstr']
+ r = random.Random(params['rndseed'])
+ dstfile = "".join([r.choice("qQoOp") for i in range(64)]) + "I.txt"
+ dstfile = dstfile.replace('O', 'I')
+ for i in range(1000):
+ start = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)])
+ mid = "".join([r.choice("uiasdfghjkyxcvbnm1234567890ASDFGHJKYZXCVBNM") for i in range(60)])
+ end = r.choice(["lz", "1z", "Iz", "iz", "l2", "I2", "12"])
+ #if start[:2] == "po" and end == "lz":
+ # start = "po"
+ # mid = "kaka"
+ x = start + mid + end
+ hidden_contents += x + "\r\n"
+ expected_contents = hidden_contents
+ #expected_contents = re.sub(r"^po.*lz\r$",
+ # r"pokakalz\r",
+ # hidden_contents,
+ # re.MULTILINE)
+ if results["dst_file_contents"] == expected_contents:
+ score += 3
+ else:
+ diff_pos = (0, "")
+ for i, c in enumerate(results["dst_file_contents"]):
+ if len(expected_contents) < i or c != expected_contents[i]:
+ start = max(0, i-10)
+ end = min(len(expected_contents), len(results["dst_file_contents"]), i+20)
+ diff_pos = (i, results["dst_file_contents"][start:end])
+ break
+ hints += ["wrong file contents\n" + str(diff_pos[1])]
+ params['dstfile'] = dstfile
+ expected_dst_ls = "-rw--w---- 1 {testuser} bilbo .*{dstfile}".format(**params)
+ if re.match(expected_dst_ls, results["dst_ls"]):
+ score += 2
+ else:
+ hints += ["missing file or wrong user/permissions\n" + results["dst_ls"] + "\n" + expected_dst_ls]
+ if results["home_ls"].find(params['dstfile']) > -1:
+ score += 2
+ expected_mnts = [
+ "/dev/sdb2 on {mntdir} type ext4".format(**params),
+ "sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)",
+ "proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)",
+ "udev on /dev type devtmpfs (rw,nosuid,relatime",
+ "/dev/sda1 on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)",]
+ if all([results["mnt"].find(expected_mnt) > -1 for expected_mnt in expected_mnts]):
+ score += 3
+ else:
+ hints += ["missing or wrong mount\n"]
+ return score, hints
+
+
+def prepare_disks(templates, task_params, global_params):
+ import random
+ import os
+
+ # first create the file contents to make it easyer to check.
+ hidden_contents = task_params['magicstr']
+ r = random.Random(task_params['rndseed'])
+ dstfile = "".join([r.choice("qQoOp") for i in range(64)]) + "I.txt"
+ for i in range(1000):
+ x = "".join([r.choice(["po", "p0", "no", "ko", "fo", "qo"]) for i in range(20)])
+ x += "".join([r.choice("uiasdfghjkyxcvbnm1234567890ASDFGHJKYZXCVBNM") for i in range(60)])
+ x += r.choice(["lz", "1z", "Iz", "iz", "l2", "I2", "12"])
+ hidden_contents += x + "\n"
+
+ # create hidden file
+ dir_list = ['Qlipper', 'Thunar', 'blender', 'autostart', 'kazam', 'mc', 'netsurf', 'pulse', 'qupzilla', 'radare2', 'teamviewer', 'texstudio', 'vlc']
+ ending_list = ['rc', '.conf', '', '.txt']
+ start_list = ['net', 'dev', 'doc', 'lib', 'time', 'conf']
+ for i in range(20):
+ start_list.append("".join([r.choice("qQoOp") for i in range(64)]) + "O")
+ r.shuffle(dir_list)
+ file_letters = ["mod", "co"]
+
+ d = templates['smallstudent-personal']
+ d.mkdir('/mnt/.hideme')
+ d.mkdir('/media/.hideme')
+ for potential_dir in dir_list:
+ try:
+ potential_dir1 = os.path.join('/mnt/.hideme', potential_dir)
+ potential_dir2 = os.path.join('/media/.hideme', potential_dir)
+ d.mkdir(potential_dir1)
+ d.chown(1001, 1001, potential_dir1)
+ d.mkdir(potential_dir2)
+ d.chown(1001, 1001, potential_dir2)
+ except:
+ pass
+ rndstr2 = dstfile
+ for i in range(r.randint(2, 20)):
+ hidden_file_name1 = os.path.join(potential_dir1,
+ rndstr2)
+ hidden_file_name2 = os.path.join(potential_dir2,
+ rndstr2)
+ d.write(hidden_file_name1, hidden_contents)
+ d.chown(1001, 1001, hidden_file_name1)
+ file_letters = ["stamp", "", "dev", "re"]
+ hidden_contents = "".join([r.choice("asdfghjkyxcvbnm1234567890 \n") for j in range(10000)])
+ d.write(hidden_file_name2, hidden_contents)
+ d.chown(1001, 1001, hidden_file_name2)
+ rndstr2 = r.choice(start_list) + \
+ r.choice(file_letters) + r.choice(ending_list)
+ file_letters = file_letters + ["mod", "co"]
+ # TODO create some additional files
+
+ # write_default_config(templates['simpleArbiterDhcpGW'], global_params)
diff --git a/tasks/set_ip_dhcp_hostname/task.py b/tasks/set_ip_dhcp_hostname/task.py
new file mode 100644
index 0000000..1007424
--- /dev/null
+++ b/tasks/set_ip_dhcp_hostname/task.py
@@ -0,0 +1,100 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Ustvari tri navidezne računalnike. Za disk prvega uporabi sliko diska simpleArbiterDhcp.
+Za enega od ostalih dveh (Z_DHCP) poskrbi, da bo dobil IP prek DHCP, pri čemer
+naj kot hostname strežniku pošlje ime, ki ga dobiš na simpleArbiterDhcp.
+Za drugega (BREZ_DHCP) poskrbi, da bo imel statično nastavljen IP.
+
+Prvi omrežni vmesnik računalnika SimpleArbiter naj bo povezan na Internet. Drugi naj bo povezan na neko lokalno omrežje, na katerega bosta priklopljena računalnika Z_DHCP ter BREZ_DHCP. Na računalniku Z_DHCP poskrbite, da bo ob pridobivanju naslova DHCP strežniku poslal tudi posebej nastavljeno ime računalnika (hostname), ki ne bo enako dejanskemu imenu računalnika (tistemu, ki ga izpiše ukaz hostname).
+
+Naslov BREZ_DHCP ter ime računalnika za Z_DHCP dobite ob zagonu run_test.py na računalniku SimpleArbiter.</pre>
+"""
+}
+
+computers = {
+ 'Z_DHCP': {
+ 'disks': [
+ { 'name': 'Z_DHCP',
+ },
+ #{ 'name': 'CDROM',
+ # 'options':{'readonly': True},
+ # 'parts': [],# no parts, no mounting.
+ #}
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'BREZ_DHCP': {
+ 'disks': [
+ { 'name': 'BREZ_DHCP',
+ },
+ #{ '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_DHCP': {'descriptions': {'si': 'Naslov za DHCP'}, 'w': False, 'public': False, 'type': 'IP', 'generated': True},
+ 'Hostname_DHCP': {'descriptions': {'si': 'Ime DHCP'}, 'w': False, 'public': True, 'type': 'hostname', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov BREZ_DHCP'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'IP_dhcp_static': {'descriptions': {'si': 'Dodeljen IP brez DHCP'}, 'w': False, 'public': False, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_DHCP, Hostname_DHCP, IP_static, MAC_static, IP_dhcp_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ # check hostname of DHCP
+ # check the hostname in the response of IP_DHCP
+ # check availability of IP_static
+ # check non-availability of IP_dhcp_static
+ return results
+
+def gen_params(user_id, params_meta):
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['IP_DHCP'], params['IP_static'], params['IP_dhcp_static'] = kpov_util.IPv4_addr_gen(r, net, 3)
+ params['Hostname_DHCP'] = kpov_util.hostname_gen(r)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['bla']:
+ score += 3
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+# d = templates['simpleArbiterDhcp']
+# create config for static_DHCP
+# set static_DHCP hostname
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
diff --git a/tasks/set_ip_static_dhcp/howtos/en/index.html b/tasks/set_ip_static_dhcp/howtos/en/index.html
new file mode 100644
index 0000000..74dfeea
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/en/index.html
@@ -0,0 +1,73 @@
+<p>
+<h2>Purpose of the assignment</h2>
+Learn how to setup network interfaces in most modern Linux distributions (NetworkManager).
+</p>
+<p>
+<h2>Quick instructions</h2>
+Set a static IP in NetworkManager, set a static IP and DNS server in /etc/network/interfaces. You'll get both IP's when you execute script run_test.py.
+</p>
+<p>
+<h2>Instructions</p>
+<ol>
+<li>From the directory with images of virtual computers, download the following:<br/> maliNetworkManager, maliBrezNetworkManager, SimpleArbiterDhcp.</li>
+
+<li>Set the network for virtual computers, so that SimpleArbiterDhcp's 1. nework interface is connected to the same network, as the only network interface for maliNetworkManager and maliBrezNetworkManager,<br/>
+ SimpleArbiterDhcp's 2. network interface will be connected to a NAT or a physical network, where the address and route (gateway) to the internet is obtained via DHCP.</li>
+
+<li>Start SimpleArbiterDhcp. Sign in as user "tester" with password "SedemKrogovPekla".</li>
+<li>
+<img alt="slika-04" src="https://lusy.fri.uni-lj.si/kpov-public-svn/kpov-public/kpov_judge/tasks/set_ip_static_dhcp/howtos/images/04.png" style="width: 800px; height: 600px;" /><br/>
+Use command <pre>ping 193.2.1.66</pre> to check if SimpleArbiterDhcp is connected to internet. If you get ping reply, you're connected to the internet. Cancel the ping with combination CTRL+C.<br/>
+ If SimpleArbiterDhcp doesn't have internet access, change the network settings in Virtual box for 1. and 2. network interface, then restart the virtual computer.
+
+</li>
+<li>Run the script run_test.py.</li>
+
+<li>Enter "03.predvaja" as assignment name.</li>
+
+<li>Read the maliNetworkManager's static IP . Leave SimpleArbiterDhcp running in the background until you have setup the maliNetworkManager.</li>
+
+<li>Start maliNetworkManager.</li>
+
+<li>
+Sign in the GUI(graphical user interface) using username "student" and password "vaje".</li>
+<li><img alt="ikona network manager" src="https://lusy.fri.uni-lj.si/kpov-public-svn/kpov-public/kpov_judge/tasks/set_ip_static_dhcp/howtos/images/10.png" style="width: 800px; height: 600px;" /><br/>
+Right click on the icon for network settings.</br>
+
+<li>
+<img alt="Menu NetworkManager" src="https://lusy.fri.uni-lj.si/kpov-public-svn/kpov-public/kpov_judge/tasks/set_ip_static_dhcp/howtos/images/11.png" style="width: 800px; height: 600px;" /><br/>
+Choose "Edit Connections"</li>
+
+<li>
+<img alt="Menu NetworkManager" src="https://lusy.fri.uni-lj.si/kpov-public-svn/kpov-public/kpov_judge/tasks/set_ip_static_dhcp/howtos/images/12.png" style="width: 800px; height: 600px;" /><br/>
+Click "Edit"</li>
+
+<li>
+<img alt="Menu NetworkManager" src="https://lusy.fri.uni-lj.si/kpov-public-svn/kpov-public/kpov_judge/tasks/set_ip_static_dhcp/howtos/images/13.png" style="width: 800px; height: 600px;" /><br/>
+In tab "IPv4" change the "Method" to "Manual". Click "Add". Set the SimpleArbiterDhcp's static IP as static IP A.<br/>
+Add Arnes DNS: 193.2.1.66 to DNS servers.
+</li>
+<li>Click "Save"</li>
+
+<li>Switch to SimpleArbiterDhcp. Click "Enter" or "OK".</li>
+
+<li>Read maliBrezNetworkManager's IP . Click "OK". Read the DNS server's address .</li>
+
+<li> Switch to maliBrezNetworkManager. Switch to first console using combination CTRL+ALT+F1. Sign in as root (su) with password "kaboom".</li>
+
+<li> Open the file /etc/network/interfaces. Edit the settings according to the information you got on SimpleArbiter. Entry for network interface should look something like this:<br/>
+<pre>
+allow-hotplug eth0
+iface eth0 inet static
+ 10.0.1.2
+ netmask 255.255.255.128
+ dns-nameservers 10.0.1.5
+</pre>
+</li>
+
+<li> Save the settings. Use the command <pre>reboot</pre> to restart maliBrezNetworkManager. On boot the NetworkManager reads which network interfaces are configured in /etc/network/interfaces. After that NetworkManager doesn't manage these interfaces anymore.</li>
+
+
+</li>Press OK on SimpleArbiterDhcp. If all went ok, you have completed this assignment.</li>
+</ol>
+</p>
diff --git a/tasks/set_ip_static_dhcp/howtos/images/04.png b/tasks/set_ip_static_dhcp/howtos/images/04.png
new file mode 100644
index 0000000..754c200
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/04.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/images/09.png b/tasks/set_ip_static_dhcp/howtos/images/09.png
new file mode 100644
index 0000000..866a51d
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/09.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/images/10.png b/tasks/set_ip_static_dhcp/howtos/images/10.png
new file mode 100644
index 0000000..d6ccf42
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/10.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/images/11.png b/tasks/set_ip_static_dhcp/howtos/images/11.png
new file mode 100644
index 0000000..10b5ec7
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/11.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/images/12.png b/tasks/set_ip_static_dhcp/howtos/images/12.png
new file mode 100644
index 0000000..0a87ae6
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/12.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/images/13.png b/tasks/set_ip_static_dhcp/howtos/images/13.png
new file mode 100644
index 0000000..e71474a
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/13.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/images/17.png b/tasks/set_ip_static_dhcp/howtos/images/17.png
new file mode 100644
index 0000000..d4bba87
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/images/17.png
Binary files differ
diff --git a/tasks/set_ip_static_dhcp/howtos/si/index.html b/tasks/set_ip_static_dhcp/howtos/si/index.html
new file mode 100644
index 0000000..6236245
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/howtos/si/index.html
@@ -0,0 +1,74 @@
+<p>
+<h2>Namen vaje</h2>
+Naučite se, kako se nastavljajo omrežni vmesniki v večini sodobnih Linux distribucij (NetworkManager).
+</p>
+<p>
+<h2>Naloga na hitro</h2>
+Nastavi statičen IP v NetworkManager-ju, nastavi statični IP in DNS strežnik v /etc/network/interfaces. Oba naslova računalnikov in DNS strežnikov dobite ob zagonu run_test.py.
+</p>
+<p>
+<h2>Navodila</p>
+<ol>
+<li>Z imenika s slikami virtualnih računalnikov povlecite slike maliNetworkManager, maliBrezNetworkManager, SimpleArbiterGW</li>
+
+<li>Nastavite omrežja navideznih računalnikov tako, da bo<br/>1. omrežni vmesnik SimpleArbiterGW povezan na isto omrežje kot edini omrežni vmesnik maliNetworkManager in maliBrezNetworkManager,<br/>
+ 2. vmesnik SimpleArbiterGW bo povezan na NAT ali fizično omrežje, kjer prek DHCP dobi naslov in pot (prehod, gateway) do Interneta.</li>
+
+<li>Zaženite SimpleArbiterGW. Prijavite se kot uporabnik tester z geslom SedemKrogovPekla</li>
+<li>
+<img alt="slika-04" src="../images/04.png" style="width: 800px; height: 600px;" /><br/>
+Z ukazom <pre>ping 8.8.8.8 </pre> preverite, ali je SimpleArbiterGW na Internetu. Če je, boste približno vsako sekundo dobili odziv. Ping prekinete
+s kombinacijo tipk CTRL+C.<br/>
+ Če SimpleArbiterGW ne pride do Interneta, v VirtualBox zamenjajte nastavitve 1. in 2. omrežni vmesnik ter ponovno zaženite navidezni računalnik.
+</li>
+<li>Poženite run_test.py.</li>
+
+<li>Kot ime naloge vpišite preparation</li>
+
+<li>Preberite statični IP maliNetworkManager. Pustite SimpleArbiterGW da teče v ozadju, dokler niste nastavili maliNetworkManager</li>
+
+<li>Zaženite maliNetworkManager.</li>
+
+<li>
+Prijavite se v grafično okolje z uporabniškim imenom student, geslom vaje</li>
+<li><img alt="ikona network manager" src="../images/10.png" style="width: 800px; height: 600px;" /><br/>
+Desno-kliknite na ikono za mrežne nastavitve.</br>
+
+<li>
+<img alt="Menu NetworkManager" src="../images/11.png" style="width: 800px; height: 600px;" /><br/>
+Izberite "Edit Connections".</li>
+
+<li>
+<img alt="Menu NetworkManager" src="../images/12.png" style="width: 800px; height: 600px;" /><br/>
+Kliknite "Edit"</li>
+
+<li>
+<img alt="Menu NetworkManager" src="../images/13.png" style="width: 800px; height: 600px;" /><br/>
+V zavihku "IPv4" spremenite "Method" na "Manual". Kliknite na "Add". Nastavite statični IP, ki ste ga prebrali na SimpleArbiterGW kot statični I.<br/>
+V DNS servers dodajte naslov DNSja, ki van ha poda run_test.py. Kot gateway dodaj IP SimpleArbiterGW.
+</li>
+<li>Kliknite "Save".</li>
+
+<li>Preklopite na SimpleArbiterGW. Pritisnite "Enter" oz. "OK".</li>
+
+<li>Preberite IP maliBrezNetworkManager. Pritisnite "OK". Preberite naslov DNS strežnika.</li>
+
+<li> Preklopite na maliBrezNetworkManager. Preklopite na prvo konzolo s kombinacijo CTRL+ALT+F1. Prijavite se kot root z geslom kaboom.</li>
+
+<li> Odprite datoteko /etc/network/interfaces. Popravite nastavitve v skladu s podatki, ki ste jih dobili na SimpleArbiter. Vnos za omrežni vmesnik mora izgledati približno takole:<br/>
+<pre>
+allow-hotplug eth0
+iface eth0 inet static
+ address "Podan IP"
+ netmask 255.255.255.0
+ dns-nameservers "Podan DNS"
+ getway "IP SimpleArbiterGW"
+</pre>
+</li>
+
+<li> Shranite nastavitve. Z ukazoma "ifdown eth0", in ifup eth0" posodobite NetworkManager ki prebere
+kateri omrežni vmesniki so nastavljeni v /etc/network/interfaces. Za te vmesnike potem ne skrbi več.</li>
+
+</li>Na SimpleArbiterGW pritisnite OK. Če je šlo vse po sreči, ste opravili tokratno nalogo.</li>
+</ol>
+</p>
diff --git a/tasks/set_ip_static_dhcp/task.py b/tasks/set_ip_static_dhcp/task.py
new file mode 100644
index 0000000..0d11f43
--- /dev/null
+++ b/tasks/set_ip_static_dhcp/task.py
@@ -0,0 +1,127 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si': '''\
+<p>
+Ustvari tri navidezne računalnike. Za prvega uporabi sliko diska <em>simpleArbiterDhcpGW</em>, za drugega sliko diska
+<em>maliNetworkManager</em>, za tretjega sliko diska <em>maliBrezNetworkManager</em>. Računalnike imenujmo enako kot slike diska.
+
+<p>
+Na <em>maliBrezNetworkManager</em> poskrbi, da NetworkManager ne bo več skrbel za omrežni vmesnik, temveč bosta delovala ukaza <code>ifup</code> in <code>ifdown</code>.
+
+<p>
+Na <em>maliNetworkManager</em> nastavi naslov IP <code>{{IP_NM}}</code> ter DNS <code>{{DNS_NM}}</code>.
+
+<p>
+Na <em>maliBrezNetworkManager</em> nastavi naslov IP <code>{{IP_static}}</code> ter DNS <code>{{DNS_static}}</code>.
+''',
+ 'en': '''\
+<p>
+Create three virtual machines. Use <em>simpleArbiterDhcpGW</em> as the disk image for the first, <em>maliNetworkManager</em> as the disk image for the second, and <em>maliBrezNetworkManager</em> for the third. The virtual machine names can match the disks.
+
+<p>
+Make sure that on <em> maliBrezNetworkManager</em> <code>ifup</code> and <code>ifdown</code> can be used to configure the network and that NetworkManager, while still installed, will not manage the network interface. The IP should be <code>{{IP_static}}</code> and the computer should use the server <code>{{DNS_static}}</code> for DNS.
+
+<p>
+On <em>maliNetworkManager</em>, set the IP address to <code>{{IP_NM}}</code> and use <code>{{DNS_NM}}</code> for DNS.
+''',
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGW',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions': {'si': 'Naslov maliNetworkManager', 'en': 'IP address for maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager', 'en': 'DNS for maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager', 'en': 'IP address for maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager', 'en':'DNS for maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ import collections
+
+ tests = (
+ ('nmcli', 'nmcli -c no d'),
+ ('nslookup', 'nslookup www.arnes.si'),
+ )
+
+ results = collections.defaultdict(str)
+ for name, host in [('nm', IP_NM), ('static', IP_static)]:
+ host_results = kpov_util.ssh_test(host, 'student', 'vaje', tests)
+ for key, value in host_results.items():
+ results[key+'-'+name] = value
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '10.94.96.0/19', 25)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+ if results['ssh-nm'] is True:
+ score += 1
+ else:
+ hints += ['mali ssh failed: ' + results['ssh-nm']]
+ if results['ssh-static'] is True:
+ score += 1
+ else:
+ hints += ['malibrez ssh failed: ' + results['ssh-static']]
+ if params['DNS_NM'] in results['nslookup-nm']:
+ score += 2
+ else:
+ hints += ['NM nslookup incorrect']
+ if params['DNS_static'] in results['nslookup-static']:
+ score += 2
+ else:
+ hints += ['static nslookup incorrect']
+ if re.search(r'e(th0|np0s3|ns3) +ethernet +connected', results['nmcli-nm']):
+ score += 2
+ else:
+ hints += ['nmcli incorrect']
+ if re.search(r'e(th0|np0s3|ns3) +ethernet +unmanaged', results['nmcli-static']):
+ score += 2
+ else:
+ hints += ['nmcli on malibrez incorrect']
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcpGW'], global_params)
diff --git a/tasks/set_motd/howtos/en/index.html b/tasks/set_motd/howtos/en/index.html
new file mode 100644
index 0000000..2987cc5
--- /dev/null
+++ b/tasks/set_motd/howtos/en/index.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>set_motd</title>
+ <meta charset="utf-8">
+</head>
+<body>
+<h1>set_motd</h1>
+<h2>Purpose of the exercise</h2>
+<p>How to create user? How to edit a file? How to connect to anoter computer using ssh? How to find out the computer IP address?</p>
+<h2>Brief description</h2>
+<p>Set up two virtual machines, set MOTD. Connect using ssh.</p>
+
+<h2>How To</h2>
+
+<ol>
+ <li>Create two virtual machines, Student(student-console) and Test(SimpleArbiterDhcpGw) <br> <img src="../images/img4.png" alt="no img"></li>
+ <li>Change the network settings to both virtual machines. SimpleArbiterDhcpGw: Adapter 1 set it to NAT for internet access, Adapter 2 to internal network for local network.
+ Student: Adapter1 set it to "internal-network" so it is in the same domestic network as SimpleArbiterDhcpGw. <br> <img src="../images/img1.png" alt="no img"> <br> <img src="../images/img2.png" alt="no img"> <br> <img src="../images/img3.png" alt="no img"></li>
+ <li>Login on <b>Student</b> <br> <img src="../images/img5.png" alt="no img"></li>
+ <li>On Student(student-console) create a new user (with "adduser username", as the task demands of you ( eg. marjankoral19 ), with a custom password. <br> <img src="../images/img6.png" alt="no img"></li>
+ <li>In Student(student-console) open interfaces file ( nano /etc/network/interfaces ) and set the IP <br>
+ <h2>How to use the <strong>nano</strong> text editor </h2>
+ <p>
+ 1.) Open the nano editor with the command nano, which is followed by the path and name of the file. Example: <strong>nano /etc/myfile</strong>. If the file doesn't exist, the file will be created by the editor.<br />
+ 2.) To move in the editor, we use the arrow keys, <strong>backspace</strong> is used for deleting. <br />
+ 3.) To save a file press the combination of keys <strong>ctrl</strong> + <strong>O</strong>. <br />
+ 4.) To exit the editor press the combination of keys <strong>ctrl</strong> + <strong>X</strong>. The editor will ask you, if you really want to exit, you can answer with <strong>y</strong> (yes ) or with <strong>n</strong> ( no ). <br />
+ 5.) To cut a line press the combination of keys <strong>ctrl</strong> + <strong>K</strong>. <br />
+ 6.) To paste a line press the combination of keys <strong>ctrl</strong> + <strong>U</strong>. <br />
+ 7.) To search over a document press the combination of keys <strong>ctrl</strong> + <strong>W</strong> and then enter the search string.
+ </p> <img src="../images/img7.png" alt="no img" ></li>
+ <li>We can check which interface belongs to which adapter in Virtual-box with MAC address. Run ifconfig command and compare the HWaddr value with the value in the Virtual-box ( settings => network => adapter => Mac address ) <br /><img src="../images/slika4.png" alt="no img" /><img src="../images/slika3.png" alt="no img"/></li>
+ <li>Then edit the /etc/motd (eg. with nano editor like this: "nano /etc/motd"), file with the specified string. (eg. "Not for Human consumption" ) <br> <img src="../images/img8.png" alt="no img"> </li>
+ <li>For testing, login with the test user into Test(SimpleArbiterDhcpGw) <br> <img src="../images/img9.png" alt="no img"></li>
+ <li>Then connect to the Student with ssh, using the user marjankoral19 - ssh marjankoral@ip. <br> <img src="../images/img10.png" alt="no img"></li>
+ <li>If the login was successful, the Message of the day should apear.</li>
+ <li>To run Kpov_judge, login onto SimpleArbiterDhcpGw, find and run the file test_task.py ( with ./test_task.py as all other scripts )<br /> <img src="../images/img11.png" alt="no img"></li>
+ <li>A window appears as we can see on the image above, then press Enter, enter your username ( eg. dr6784@student.uni-lj.si ), password, task name (eg. 01-preparation-set_motd), enter the string we should get in motd, enter the username and password of a user on Student(student-console)(eg. marjankoral19), the IP of Student(student-console), and after a brief moment we should get the result. <img src="../images/img12.png" alt="no img"> </li>
+</ol>
+
+
+</body>
+</html> \ No newline at end of file
diff --git a/tasks/set_motd/howtos/images/first.png b/tasks/set_motd/howtos/images/first.png
new file mode 100644
index 0000000..d3797d7
--- /dev/null
+++ b/tasks/set_motd/howtos/images/first.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img1.png b/tasks/set_motd/howtos/images/img1.png
new file mode 100644
index 0000000..2ed7899
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img1.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img10.png b/tasks/set_motd/howtos/images/img10.png
new file mode 100644
index 0000000..dca77ef
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img10.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img11.png b/tasks/set_motd/howtos/images/img11.png
new file mode 100644
index 0000000..f42e7b0
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img11.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img12.png b/tasks/set_motd/howtos/images/img12.png
new file mode 100644
index 0000000..73ffb65
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img12.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img2.png b/tasks/set_motd/howtos/images/img2.png
new file mode 100644
index 0000000..51688ac
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img2.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img3.png b/tasks/set_motd/howtos/images/img3.png
new file mode 100644
index 0000000..93a8acf
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img3.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img4.png b/tasks/set_motd/howtos/images/img4.png
new file mode 100644
index 0000000..e5e21f9
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img4.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img5.png b/tasks/set_motd/howtos/images/img5.png
new file mode 100644
index 0000000..a128781
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img5.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img6.png b/tasks/set_motd/howtos/images/img6.png
new file mode 100644
index 0000000..b10bf9a
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img6.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img7.png b/tasks/set_motd/howtos/images/img7.png
new file mode 100644
index 0000000..40ce63d
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img7.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img8.png b/tasks/set_motd/howtos/images/img8.png
new file mode 100644
index 0000000..b7bd3b8
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img8.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/img9.png b/tasks/set_motd/howtos/images/img9.png
new file mode 100644
index 0000000..20a2439
--- /dev/null
+++ b/tasks/set_motd/howtos/images/img9.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/second.png b/tasks/set_motd/howtos/images/second.png
new file mode 100644
index 0000000..61bea73
--- /dev/null
+++ b/tasks/set_motd/howtos/images/second.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/slika3.png b/tasks/set_motd/howtos/images/slika3.png
new file mode 100644
index 0000000..05ca178
--- /dev/null
+++ b/tasks/set_motd/howtos/images/slika3.png
Binary files differ
diff --git a/tasks/set_motd/howtos/images/slika4.png b/tasks/set_motd/howtos/images/slika4.png
new file mode 100644
index 0000000..b99df06
--- /dev/null
+++ b/tasks/set_motd/howtos/images/slika4.png
Binary files differ
diff --git a/tasks/set_motd/howtos/si/index.html b/tasks/set_motd/howtos/si/index.html
new file mode 100644
index 0000000..601b667
--- /dev/null
+++ b/tasks/set_motd/howtos/si/index.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>set_motd</title>
+<meta charset="utf-8">
+</head>
+<body>
+<h1>set_motd</h1>
+<h2>Namen vaje</h2>
+<p>Kako se ustvari uporabnik? Kako se popravi datoteka? Kako se s pomočjo ssh
+povežemo na drug racunalnik? Kako ugotovimo IP naslov računalnika? </p>
+
+<h2>Naloga na hitro</h2>
+<p>Postavi 2 navidezna računalnika, nastavi MOTD. Poveži se preko ssh.</p>
+
+<h2>Podrobna navodila</h2>
+
+<ol>
+ <li>Ustvari dva navidezna računalnika, računalnik Student(student-console) ter računalnik Test(SimpleArbiterDhcpGw) <br> <img src="../images/img4.png" alt="ni slike"></li>
+ <li>Spremeni omrežne nastavitve obema navideznima računalnikoma, SimpleArbiterDhcpGw: Adapter 1 na NAT za dostop do interneta, Adapter 2 na "internal network" za lokalno omrežje,
+ Student: Adapter1 na internal-network, da je v enakem omrežju kot SimpleArbiterDhcpGw. <br> <img src="../images/img1.png" alt="ni slike" > <br> <img src="../images/img2.png" alt="ni slike"> <br> <img src="../images/img3.png" alt="ni slike"></li>
+ <li>Prijavi se na računalniku Student. <br> <img src="../images/img5.png" alt="ni slike"></li>
+ <li>Na računalniku Student(student-console) ustvari novega uporabnika (z ukazom "adduser imeuporabnika"), kot to od tebe zahteva naloga (npr. marjankoral19), geslo določi sam. <br> <img src="../images/img6.png" alt="ni slike"></li>
+ <li>Računalnik Student, odpri datoteko interfaces ( nano /etc/network/interfaces ), ter nastavi IP. <br> <img src="../images/img7.png" alt="ni slike"></li>
+ <h2>Kako se uporablja <strong>nano</strong> urejavalnika besedila: </h2>
+ <p>
+ 1.) Urejvalnik Nano odpremo z ukazom nano, kateremu sledi ime datoteke. Primer: <strong>nano /etc/mojadatoteka</strong>. Če datoteka ne obstaja jo bo ustvaril urejevalnik. <br />
+ 2.) Po urejevalniku se premikamo s smernimi puščicami, brišemo s tipko <strong>backspace</strong>. <br />
+ 3.) Za shranjevanje dokumenta pritisnemo kombinacijo tipk <strong>ctrl</strong> + <strong>O</strong> <br />
+ 4.) Za izhod iz urejevalnika pritisnemo kombinacijo tipk <strong>ctrl</strong> + <strong>X</strong>. Pri tem nas urejevalnik upraša, če želimo shraniti spremembe. Odgovorimo z <strong>y</strong> (yes, ja ) ali z <strong>n</strong> ( no, ne ). <br />
+ 5.) Za izrez vrstice uporabimo kombinacijo tipk <strong>ctrl</strong> + <strong>K</strong>. <br />
+ 6.) Za lepljenje vrstice se uporablja kombinacija tipk <strong>ctrl</strong> + <strong>U</strong>. <br />
+ 7.) Za iskanje po besedilu uporabimo kombinacijo tipk <strong>ctrl</strong> + <strong>W</strong>, nakar vnesemo iskani niz in pritisnemo tipko enter.
+ </p><br />
+ <li>Kateri vmesnik (npr. eth0) spada pod kateri adapter (npr. Adapter1 ), lahko preverimo s strojnimi naslovi. Na računalniku zaženemo ukaz ifconfig, pogledamo HWaddr vrednost ter jo primerjamo z vrednostjo v Virtual-boxu (nastavitve => omrežja => adapter => MAC address <br /><img src="../images/slika4.png" alt="ni slike"/><img src="../images/slika3.png" alt="ni slike"/></li>
+ <li>Nato spremeni datoteko /etc/motd (z urejevalnikom nano, primer uporabe: "nano /etc/motd"), ter zamenjaj niz z ustreznim nizom kot to od tebe zahteva naloga ( npr. "Not for Human consumption" ) <br>
+ <img src="../images/img8.png" alt="ni slike"> </li>
+ <li>Za testiranje se s testnim uporabniškim imenom prijavi na prvem računalniku. (SimpleArbiterDhcpGw) <br> <img src="../images/img9.png" alt="ni slike"></li>
+ <li>Nato se preko ssh poveži na računalnik Student z uporabniškim imenom marjankoral19 - ssh marjankoral19@ip. <br> <img src="../images/img10.png" alt="ni slike" ></li>
+ <li>Po uspešni prijavi se bi moralo izpisati motd sporočilo.</li>
+ <li>Kpov_judge poženemo tako da se prijavimo na računalniku SimpleArbiterDhcpGw, najdemo datoteko test_task.py ter jo poženemo ( z ./test_task.py kot se poganjajo vse skripte )<br /> <img src="../images/img11.png" alt="ni slike"></li>
+ <li>Pojavi se nam okno kot ga vidimo zgoraj, nato pa pritisnemo tipko Enter, vnesemo svoje uporabniško ime ( npr. dr6784@student.uni-lj.si ), geslo, ime naloge (npr. 01-preparation-set_motd), vnesemo niz ki bi se nam moral prikazati, vnesemo ime uporabnika na računalniku Student (npr. marjankoral19) ter njegovo geslo, ip računalnika študent, nato pa po kratkem premoru dobimo rezultat. <img src="../images/img12.png" alt="ni slike"> </li>
+</ol>
+
+</body>
+</html> \ No newline at end of file
diff --git a/tasks/set_motd/task.py b/tasks/set_motd/task.py
new file mode 100644
index 0000000..89b78f6
--- /dev/null
+++ b/tasks/set_motd/task.py
@@ -0,0 +1,86 @@
+instructions = {
+ 'si': '''\
+<p>
+Ustvari dva navidezna računalnika - imenujmo ju <em>arbiter</em> in <em>student</em>.
+Na računalniku <em>student</em> ustvarite uporabnika z uporabniškim imenom <code>{{peer_user}}</code>. IP navideznega računalnika <em>student</em> ter geslo za uporabnika <code>{{peer_user}}</code> nastavite sami.
+
+<p>
+Poskrbite, da se bo v sporočilu, ki se ob prijavi izpiše na računalniku <em>student</em>, pojavil niz
+
+<pre><code>{{niz}}</code></pre>
+
+<p>
+Temu sporočilu v angleščini rečemo <em lang="en">message of the day</em> oziroma <em>MOTD</em>. Ocenjevalni program pričakuje, da se bo ob koncu prijave pojavila ukazna vrstica oblike
+
+<pre><code>username@hostname:~$ </code></pre>
+
+Pazite, da se bo takšna vrstica pojavila šele po nizu, ki ste ga dobili v teh navodilih.
+ ''',
+ 'en': '''\
+<p>
+Create two virtual machines named <em>arbiter</em> and <em>student</em>. On <em>student</em>, create a user with the username <code>{{peer_user}}</code>. Set the IP of <em>student</em> and the password for <code>{{peer_user}}</code> yourself.
+
+<p>
+Set the <em>message of the day</em> (MOTD) on <em>student</em> to
+
+<pre><code>{{niz}}</code></pre>
+
+<p>
+This is the message which is displayed when you log in. The grading system expects that after login a prompt similar to
+
+<pre><code>username@hostname:~$ </code></pre>
+
+<p>
+appears. Make sure that this line shows up only after the string you got in these instructions.
+'''
+}
+
+computers = {
+ 'arbiter': {
+ 'disks': [{'name': 'dhcp-gw'}],
+ 'flavor': 'm1.tiny',
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'config_drive': True,
+ 'userdata': {'string': "#!/bin/bash\nsed -i '/cloud/d' /etc/fstab\npoweroff &\n"}
+ },
+ 'student': {
+ 'disks': [{ 'name': 'console'}],
+ 'flavor': 'm1.tiny',
+ 'network_interfaces': [{'network': 'net1'}],
+ 'config_drive': True,
+ 'userdata': {'string': "#!/bin/bash\nsed -i '/cloud/d' /etc/fstab\npoweroff &\n"}
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'peer_ip': {'descriptions': {'si': 'IP računalnika', 'en':'IP'}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
+ 'peer_user': {'descriptions': {'si': 'ime uporabnika', 'en':'Username'}, 'w': False, 'public': True, 'type': 'username', 'generated': True},
+ 'peer_passwd': {'descriptions': {'si': 'geslo uporabnika', 'en': 'Password'}, 'w': True, 'public': True, 'type': 'alnumstr', 'generated': False},
+ 'niz': {'descriptions':{'si': 'niz, ki naj se v motd pokaže', 'en': 'The string which should be displayed in the MOTD'}, 'w': False, 'public': True, 'type': 'short_text', 'generated': True},
+}
+
+def task(peer_ip, peer_user, peer_passwd, niz):
+ "Check whether ssh works and return the MOTD."
+ return kpov_util.ssh_test(peer_ip, peer_user, peer_passwd)
+
+def gen_params(user_id, params_meta):
+ return kpov_util.default_gen(user_id, params_meta)
+
+def task_check(results, params):
+ niz = params['niz']
+ score = 0
+ hints = []
+ if results['ssh'] is True:
+ score += 4
+ if niz in results['motd']:
+ score += 6
+ else:
+ hints += ['wrong motd:\n' + results['motd'] + '\n']
+ else:
+ hints += ['ssh failed: ' + results['ssh']]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['dhcp-gw'], global_params)
diff --git a/tasks/smb_nfs/howtos/en/index.html b/tasks/smb_nfs/howtos/en/index.html
new file mode 100644
index 0000000..fe056b4
--- /dev/null
+++ b/tasks/smb_nfs/howtos/en/index.html
@@ -0,0 +1,341 @@
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html" charset="utf-8">
+<title>smb_nfs</title>
+<style type="text/css">
+ #code {
+ font-family: Courier New;
+ font-size: 12;
+ }
+</style>
+</head>
+<body>
+ <h1>
+ smb_nfs
+ </h1>
+ <p>
+ <a href="#vb">VirtualBox</a> | <a href="#server">Server</a> | <a href="#client">Client</a> | <a href="#nfs">NFS</a> | <a href="#smb">Samba</a> | <a href="#dhcp">DHCP</a>
+ </p>
+ <h2>
+ Quick guide
+ </h2>
+ <p>
+ Set up two virtual computers - SimpleArbiterDhcp and FileServer.
+ </p>
+ <p>
+ Make sure that the directory /srv/nfs/ERLbbBrT on FileServer is accessible
+ over NFS and over SMB under the sharename urania-03.
+ Set the SMB server name to zarptica-32.
+ </p>
+ <p>
+ SimpleArbiterDhcp should have write access to /srv/nfs/ERLbbBrT over NFS.
+ </p>
+
+ <h2>
+ Instructions
+ </h2>
+ <ul style="list-style: none;">
+ <li>
+ <h3>
+ Download these VM images:
+ </h3>
+ <ul type="disc">
+ <li>
+ student-fileserver.vdi
+ </li>
+ <li>
+ simpleArbiterDhcpGW.vdi
+ </li>
+ <br>
+ </ul>
+ </li>
+ <a name="vb"></a>
+ <li>
+ <h3>
+ VirtualBox Settings:
+ </h3>
+ <ul type="disc">
+ <li>
+ Enable PAE/NX for both VMs: Settings&rArr;System&rArr;Processor
+ </li>
+ <li>
+ For FileServer
+ <ul>
+ <li>
+ Adapter 1 - NAT
+ </li>
+ <li>
+ Adapter 2 - Internal Network
+ </li>
+ </ul>
+ </li>
+ <li>
+ For SimpleArbiterDhcp
+ <ul>
+ <li>
+ Adapter 1 - Internal Network
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <br>
+ <a name="server"></a>
+ <li>
+ <h3>
+ Server FileServer
+ </h3>
+ <ol>
+ <a name="dhcp"></a>
+ <li>
+ Set up a DHCP server
+ <ol>
+ <li>
+ <span id="code">
+ apt-get update
+ </span>
+ </li>
+ <li>
+ <span id="code">
+ apt-get install isc-dhcp-server
+ </span>
+ </li>
+ <li>
+ The server will not start (error
+ <span id="code">
+ Starting ISC DHCP server: dhcpdcheck syslog for diagnostics. ... failed!</span>)
+ , configure 3 files:
+ <ul>
+ <li>
+ In /etc/network/interfaces set static IP for eth1 on which the DHCP server will be running,
+ e.g.:
+ <p id="code">
+ auto eth1<br>
+ iface eth1 inet static<br>
+ address 192.168.1.10<br>
+ netmask 255.255.255.0<br>
+ network 192.168.1.0<br>
+ broadcast 192.168.1.255<br>
+ </p>
+ </li>
+ <li>
+ In /etc/default/isc-dhcp-server:
+ <p id="code">
+ INTERFACES="eth1"
+ </p>
+ </li>
+ <li>
+ In /etc/dhcp/dhcpd.conf configure the subnet properties,
+ e.g.:
+ <p id="code">
+ authoritative;<br>
+ default-lease-time 600;<br>
+ max-lease-time 7200;<br>
+ <br>
+ subnet 192.168.1.0 netmask 255.255.255.0 {<br>
+ range 192.168.1.100 192.168.1.200;<br>
+ option routers 192.168.1.10;<br>
+ option domain-name-servers 193.2.1.66, 8.8.4.4;<br>
+ <br>
+ host SimpleArbiter {<br>
+ hardware ethernet 08:00:27:A2:FB:B4;<br>
+ fixed-address 192.168.1.180;<br>
+ }<br>
+ }<br>
+ </p>
+ </li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <a name="nfs"></a>
+ <li>
+ Set up a NFS server
+ <ol>
+ <li>
+ apt-get install nfs-kernel-server
+ </li>
+ <li>
+ Determine the rules in /etc/exports, e.g.:
+ <p id="code">
+ #privileges for SimpleArbiterDhcp<br>
+ /srv/nfs/ERLbbBrT 192.168.1.180(rw,sync,insecure)<br>
+ /srv/nfs/ERLbbBrT 192.168.1.0/24(ro,sync,insecure)<br>
+ </p>
+ </li>
+ <li>
+ Change the owner of the directory and files in it:
+ <span id="code">
+ chown student /srv/nfs/ERLbbBrT
+ </span>
+ and similarly for all the files in shared directory. The owner should not be root.
+ </li>
+ <li>
+ Run command
+ <span id="code">exportfs -rv</span>
+ to export file systems
+ <p>After that run
+ <span id="code">
+ services nfs-kernel-server restart
+ </span>
+ </p>
+ </li>
+ <br>
+ </ol>
+ </li>
+ <a name="smb"></a>
+ <li>
+ Set up SMB server
+ <ol>
+ <li>
+ <span id="code">
+ apt-get install samba
+ </span>
+ </li>
+ <li>
+ Create directory urania-03 and set owner and privileges:
+ <p id="code">
+ mkdir /home/student/urania-03<br>
+ chown -R root:users /home/urania-03/<br>
+ chmod -R ug+rwx,o+rx+w /home/urania-03<br>
+ </p>
+ </li>
+ <li>
+ Edit configurations in /etc/samba/smb.conf, add at the bottom of document, e.g.:
+ <p id="code">
+ [global]<br>
+ workgroup = users<br>
+ server string = zarptica-32<br>
+ dns proxy = no<br>
+ log file = /var/log/samba/log.%m<br>
+ max log size = 1000<br>
+ syslog = 0<br>
+ panic action = /usr/share/samba/panic-action %d <br>
+ security = user<br>
+ encrypt passwords = yes<br>
+ passdb backend = tdbsam<br>
+ obey pam restrictions = yes<br>
+ unix password sync = yes<br>
+ passwd program = /usr/bin/passwd %u<br>
+ passwd chat = *Enter\snew\s*\spassword:* %n\n <br>*Retype\snew\s*\spassword:* %n\n <br>*password\supdated\ssuccessfully* .<br>
+ pam password change = yes<br>
+ map to guest = bad user<br>
+ usershare allow guests = yes<br>
+ <br>
+ [homes]<br>
+ comment = Home Directories<br>
+ browseable = no<br>
+ read only = yes<br>
+ create mask = 0700<br>
+ directory mask = 0700<br>
+ valid users = %S<br>
+ <br>
+ [printers]<br>
+ comment = ALl Printers<br>
+ browseable = no<br>
+ path = /var/spool/samba<br>
+ printable = yes<br>
+ guest ok = no<br>
+ read only = yes<br>
+ create mask = 0700<br>
+ <br>
+ [print$]<br>
+ comment = Printer Drivers<br>
+ path = /var/lib/samba/printers<br>
+ browseable = yes<br>
+ read only = yes<br>
+ guest ok = no<br>
+ <br>
+ [urania-03]<br>
+ comment = All Users<br>
+ path = /home/urania-03<br>
+ users = @users<br>
+ force group = users
+ create mask = 0660<br>
+ directory mask = 0771<br>
+ writable = yes<br>
+ </p>
+ </li>
+ <li>
+ Restart Samba:
+ <span id="code">
+ service samba restart
+ </span>
+ </li>
+ <li style="list-style-type:none;">
+ <p>
+ Test the syntax of smb.conf file with command
+ <span id="code">
+ testparam
+ </span>
+ </p>
+ </li>
+ <li>
+ Add users:
+ <p>
+ In order to define passwords for Samba users they have to exist on a local system, too.
+ <p>
+ Use command
+ <span id="code">
+ useradd USERNAME --shell /bin/false
+ </span>
+ to create user with a disabled account and without home directory, e.g:
+ <p id="code">
+ useradd tester --shell /bin/false
+ </p>
+ </p>
+ <p>
+ Define Samba password for your user:
+ <p id="code">
+ smbpasswd -a tester
+ </p>
+ <p>
+ Add the user to your group.
+ <p>
+ Open /etc/group file and add group and users:
+ <span id="code">
+ users:x:1002:tester
+ </span>
+ </p>
+ </p>
+ <li> Restart Samba.
+ </li>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <br>
+ <a name="client"></a>
+ <li>
+ <h3>
+ Client SimpleArbiterDhcp
+ </h3>
+ <ul type="disc">
+ <li>Create directories for your mounts, e.g.:
+ <p id="code">
+ mkdir mnt<br>
+ mkdir mnt/smb<br>
+ mkdir mnt/nfs<br>
+ </p>
+ </li>
+ <li>
+ NFS: Run command
+ <p id="code">
+ sudo mount 192.168.1.10:/srv/nfs/ERLbbBrT /mnt/nfs
+ </p>
+ </li>
+ <li>
+ SMB: Run command
+ <p id="code">
+ sudo mount -t cifs //192.168.1.10/urania-03 /mnt/smb -o username=tester,password=test,workgroup=users<br>
+ </p>
+ </li>
+ <p>
+ You should be able to access shared folders now.
+ </p>
+ </ul>
+ </li>
+ </ul>
+</body>
+</html> \ No newline at end of file
diff --git a/tasks/smb_nfs/howtos/images/parameters.png b/tasks/smb_nfs/howtos/images/parameters.png
new file mode 100644
index 0000000..7d3db83
--- /dev/null
+++ b/tasks/smb_nfs/howtos/images/parameters.png
Binary files differ
diff --git a/tasks/smb_nfs/howtos/si/index.html b/tasks/smb_nfs/howtos/si/index.html
new file mode 100644
index 0000000..80d910d
--- /dev/null
+++ b/tasks/smb_nfs/howtos/si/index.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="sl">
+
+<head>
+ <title>SMB NFS How To</title>
+ <meta charset="utf-8" />
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
+</head>
+
+<body class="container">
+ <h1>KPOV Judge 7 (SMB NFS)</h1>
+ <p>V tej vaji postavimo na linux-u strežnik za nudenje datotek prek mreže in strežnik za SMB, s katerim lahko na Windows sistemih postavimo datoteko v skupno rabo. Pazi da bo simpleArbiterDhcpGW imel NFS pravico pisanja po imeniku!</p>
+ <h2>Virtualni računalniki</h2>
+ <ul>
+ <li>simpleArbiterDhcpGW</li>
+ <li>student-fileserver</li>
+ </ul>
+ <h3>simpleArbiterDhcpGW</h3>
+ <p>Naj ima 2 omrežna vmesnika, prvi naj bo preko NAT povezan na svetovni splet, drugi vmesnik pa naj vsebuje interno povezavo znotraj virtualnih sistemov na tvojem računalniku “<i>intnet</i>”.</p>
+ <h3>student-fileserver</h3>
+ <p>Naj ima 1 omrežni vmesnik, povezan na interno omrežje “<i>intnet</i>”.</p>
+ <h2>Parametri</h2>
+ <div class="figure">
+ <img src="../images/parameters.png" alt="Parametri" />
+ <p class="caption">Parametri za reševanje naloge</p>
+ </div>
+ <p>Tokrat imamo tri parametre. “Imenovani” <strong>dir</strong>, <strong>smb-share</strong>, <strong>smb-server</strong>.</p>
+ <p>Oziroma iz slike so to: </p>
+ <ul>
+ <li><strong>dir</strong> = TeNVU74X</li>
+ <li><strong>smb-share</strong> = aurora-85</li>
+ <li><strong>smb-server</strong> = melete-04</li>
+ </ul>
+ <h2>Postopek</h2>
+ <p>Ko zaženemo simpleArbiterDhcpGW in student-fileserver se najprej prijavimo v oba sistema. Nato pa na student-fileserver poženemo</p>
+ <div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="ex">apt-get</span> update <span class="kw">&amp;&amp;</span> <span class="ex">apt-get</span> install nfs-kernel-server samba</code></pre></div>
+ <h3>Nastavitve NFS</h3>
+ <p>V datoteki <code>/etc/exports</code> dodamo sledečo vrtstico: <code>/srv/nfs/[dir] [IP simpleArbiterDhcpGW](rw)</code>.</p> <p>Datoteko shranimo in znova poženemo NFS strežnik.</p>
+ <div class="sourceCode"><pre class="sourceCode bash"><span class="ex">service</span> nfs-kernel-server restart</pre></div>
+ <p>Ustvarimo imenik, ki smo ga malce prej navedli v nastavitvah NFS. In nato omogočimo vsem pisanje po tem imeniku.</p>
+ <div class="sourceCode">
+ <pre class="sourceCode bash">
+<span class="fu">mkdir</span> /srv/nfs/[dir]
+<span class="fu">chmod</span> oug+w /srv/nfs/[dir]
+</pre>
+ </div>
+ <h3>Nastavitve SMB</h3>
+ <p>Vse nastavitvene datoteke SMB se nahajajo v imeniku: <code>/etc/samba</code>. Zanima pa nas datoteka <code>smb.conf</code>.</p>
+ <div class="sourceCode"><pre class="sourceCode bash"><span class="co"># Datoteka smb.conf</span>
+ [<span class="ex">global</span>]
+
+ <span class="ex">workgroup</span> = WORKGROUP
+ <span class="ex">netbios</span> name = [smb-server] <span class="co"># Nadomestek DNS, ki si ga je izmislil Microsoft</span>
+
+ <span class="co"># Malce nižje pod vrstico =========== Share Definitions =========== dodamo svoje nastavitve</span>
+
+ [[<span class="ex">smb-share</span>]] <span class="co"># Primer iz slike: [aurora-85]</span>
+ <span class="ex">path</span> = /srv/nfs/[dir]
+ <span class="bu">read</span> <span class="va">only</span> <span class="va">=</span> <span class="va">no</span>
+ <span class="ex">guest</span> ok = yes
+ <span class="ex">browseable</span> = yes</pre></div>
+ <p>Ko popravimo to datoteko restartamo SMB in NetBios s spodnjima ukazoma.</p>
+ <div class="sourceCode"><pre class="sourceCode bash"><span class="ex">service</span> smbd restart
+<span class="ex">service</span> nmbd restart</pre></div>
+ <h2>Testiranje</h2>
+ <p>Sedaj samo še testiranje :) Za to pa na <strong>simpleArbiterDhcpGW</strong> poženi testno skripto.</p>
+ <div class="sourceCode"><pre class="sourceCode bash"><span class="ex">./test_task.py</span></pre></div>
+
+</body>
+
+</html>
diff --git a/tasks/smb_nfs/task.py b/tasks/smb_nfs/task.py
new file mode 100644
index 0000000..6d1e51d
--- /dev/null
+++ b/tasks/smb_nfs/task.py
@@ -0,0 +1,138 @@
+# kpov_util should be imported by add_assignment.py
+
+# TODO: dokoncaj!
+instructions = {
+ 'si': '''\
+<p>
+Postavi dva navidezna računalnika: <em>simpleArbiterDhcp</em> in <em>FileServer</em>.
+
+<p>
+Poskrbi, da bo imenik <code>{{NFS_MOUNT}}</code> na <em>FileServer</em> dostopen prek NFS in prek SMB kot imenik v skupni rabi <code>{{SMB_SHARENAME}}</code>. Ime strežnika SMB nastavite na <code>{{FILESERVER_NAME}}</code>.
+
+<p>
+<em>SimpleArbiterDhcp</em> naj ima prek NFS pravico pisati po imeniku.
+''',
+ 'en': '''\
+<p>
+Set up two virtual computers: <em>simpleArbiterDhcp</em> and <em>FileServer</em>.
+
+<p>
+Make sure that the directory <code>{{NFS_MOUNT}}</code> on <em>FileServer</em> is accessible over NFS and over SMB under the sharename <code>{{SMB_SHARENAME}}</code>. Set the SMB server name to <code>{{FILESERVER_NAME}}</code>.
+
+<p>
+<em>SimpleArbiterDhcp</em> should have write access to <code>{{NFS_MOUNT}}</code> over NFS.
+''',
+}
+
+computers = {
+ 'FileServer': {
+ 'disks': [
+ { 'name': 'student-fileserver',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGW',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'FILESERVER_IP': {'descriptions': {'si': 'IP streznika'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'FILESERVER_NAME': {'descriptions': {'si': 'Ime streznika'}, 'w': False, 'public':True, 'type': 'hostname', 'generated': True},
+ 'SMB_SHARENAME': {'descriptions': {'si': 'Ime imenika v skupni rabi prek SMB', 'en': 'SMB sharename'}, 'w': False, 'public':True, 'type': 'filename', 'generated': True},
+ 'NFS_MOUNT': {'descriptions': {'si': 'Imenik, dostopen prek NFS'}, 'w': False, 'public': True, 'type': 'filename', 'generated': True},
+ 'SHARED_FILENAME': {'descriptions': {'si': 'Iskana datoteka'}, 'w': False, 'public': True, 'type': 'filename', 'generated': True},
+ 'SHARED_CONTENT': {'descriptions': {'si': 'Vsebina iskane datoteke'}, 'w': False, 'public': False, 'type': 'short', 'generated': True},
+ 'SHARED_FILE_SEED': {'descriptions': {'si': 'Dodatni podatek za testiranje'}, 'w': False, 'public': True, 'type': 'filename', 'generated': True},
+}
+
+def task(FILESERVER_IP, FILESERVER_NAME, NFS_MOUNT, SMB_SHARENAME, SHARED_FILE_SEED):
+ import pexpect
+ import random
+ # TODO: (polz) Try using pexpect instead of subprocess, it's much nicer.
+ # Tabela vseh mountov.
+ # Samo mounti na streznik.
+ results = dict()
+ results['mount'] = pexpect.run('mount')
+ results['try_mount_nfs'] = pexpect.run('sudo mount -t nfs {}:/{} /mnt/nfs'.format(
+ FILESERVER_IP, NFS_MOUNT))
+ results['try_mount_smb'] = pexpect.run(
+ 'sudo mount -t cifs //{}/{} /mnt/smb -o ip={},guest'.format(
+ FILESERVER_NAME, SMB_SHARENAME, FILESERVER_IP))
+ results['mount_after'] = pexpect.run('mount')
+ results['ls_smbmount'] = pexpect.run('ls /mnt/smb')
+ results['ls_nfs'] = pexpect.run('ls /mnt/nfs')
+ r = random.Random(SHARED_FILE_SEED)
+ testfile = kpov_util.fname_gen(r)
+ teststring = kpov_util.alnum_gen(r, 200)
+ with open('/mnt/nfs/{}'.format(testfile),'w') as f:
+ f.write(teststring)
+ results['filestr'] = pexpect.run(
+ 'cat /mnt/smb/{}'.format(testfile))
+ results['filels'] = pexpect.run(
+ 'ls /mnt/smb/'.format(testfile))
+ pexpect.run('rm /mnt/nfs/{}'.format(testfile))
+ results['filels_later'] = pexpect.run('ls /mnt/smb')
+ pexpect.run("sudo umount /mnt/nfs")
+ pexpect.run("sudo umount /mnt/smb")
+ return results
+
+def gen_params(user_id, params_meta):
+ d = kpov_util.default_gen(user_id, params_meta)
+ r = random.Random(user_id)
+ d['FILESERVER_NAME'] = kpov_util.hostname_gen(r)
+ d['SMB_SHARENAME'] = kpov_util.hostname_gen(r)
+ d['NFS_MOUNT'] = "/srv/nfs/" + kpov_util.fname_gen(r, False)
+ d['SHARED_FILENAME'] = kpov_util.fname_gen(r)
+ d['SHARED_CONTENT'] = kpov_util.fortune(r, 4096)
+ d['SHARED_FILE_SEED'] = kpov_util.alnum_gen(r, 42)
+ return d
+
+def task_check(results, params):
+ score = 0
+ hints = []
+ r = random.Random(params['SHARED_FILE_SEED'])
+ testfile = kpov_util.fname_gen(r)
+ teststring = kpov_util.alnum_gen(r, 200)
+ # no need to check results['mount'] or results['try_mount_nfs']
+ # or results['try_mount_smb']
+ if results['mount_after'].find('//{}/{} on /mnt/smb type cifs'.format(
+ params['FILESERVER_NAME'], params['SMB_SHARENAME'])) >= 0:
+ score += 2
+ if results['mount_after'].find('{}:{} on /mnt/nfs type nfs'.format(
+ params['FILESERVER_IP'], params['NFS_MOUNT'])) >= 0:
+ score += 2
+ if results['ls_smbmount'].find(params['SHARED_FILENAME']) >= 0:
+ score += 1
+ if results['ls_nfs'].find(params['SHARED_FILENAME']) >= 0:
+ score += 1
+ if results['filestr'] == teststring:
+ score += 2
+ filels_later = set(results['filels_later'].split())
+ filels = set(results['filels'].split())
+ if "".join(filels - filels_later).find(testfile) >= 0:
+ score += 2
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ d = templates['student-fileserver']
+ d.mkdir("/srv/nfs")
+ d.mkdir(task_params['NFS_MOUNT'])
+ d.write(task_params['NFS_MOUNT'] + "/" + task_params["SHARED_FILENAME"],
+ task_params["SHARED_CONTENT"])
+ d = templates['simpleArbiterDhcpGW']
+ d.mkdir('/mnt/nfs')
+ d.mkdir('/mnt/smb')
+ write_default_config(templates['simpleArbiterDhcpGW'], global_params)
diff --git a/tasks/snmp_agent_uptime/howtos/en/index.html b/tasks/snmp_agent_uptime/howtos/en/index.html
new file mode 100644
index 0000000..bef6792
--- /dev/null
+++ b/tasks/snmp_agent_uptime/howtos/en/index.html
@@ -0,0 +1,319 @@
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>snmp_agent_uptime</title>
+ </head>
+ <body>
+ <h1>snmp_agent_uptime</h1>
+ <h2>Quick instructions</h2>
+ <p>
+ Set up three virtual computers, SimpleArbiter with the disk image
+ simpleArbiterDhcp, SNMPServer and SNMPClient. Write a program
+ called upminutes. This program should output the uptime of the
+ computer in minutes. Set it up on SNMPClient in the home directory
+ of the user test with the password test.
+ </p>
+ <p>
+ Make sure that the SNMP server reports it's uptime in seconds
+ over SNMP under NET-SNMP-EXTEND-MIB::nsExtendOutput2Table.
+ </p>
+ <p>
+ Write a script called beri.sh that reads the value from the
+ OID 1.3.6.1.4.1.8072.1.3.2.4.1.2 on SNMPServer. Set it up on
+ SNMPClient in the home directory of the user test.
+ </p>
+ <h2>Instructions</h2>
+ <h3>Set up of VM VirtualBox</h3>
+ <ol>
+ <li>
+ Download the following virtual images (*.vid) from the directory
+ with images of virtual computers:
+ <ol type="disc">
+ <li>
+ simpleArbiterDhcp.vdi
+ </li>
+ <li>
+ some-bash-console.vdi – twice, one for SNMPServer
+ and second for SNMPClient
+ </li>
+ </ol>
+ </li>
+ <li>
+ VM VirtualBox WARNING! If you want to use one same virtual image
+ (some-bash-console.vdi) for two virtual computers
+ (SNMPServer and SNMPClient), you must <strong>change UUID</strong>
+ of one image.
+ <ol type="disc">
+ <li>
+ Use this command
+ <i>vboxmanage internalcommands sethduuid name-of-disk.vdi</i>
+ to change UUID (<a href="http://www.giannistsakiris.com/2009/05/06/virtualbox-how-to-change-the-uuid-of-virtual-disk-vdi/">hint</a>).
+ </li>
+ </ol>
+ </li>
+ <li>
+ Final view of sets VM VirtualBox machines.<br>
+ <img src="../images/01.png" alt="VM VirtualBox machines" width="800">
+ </li>
+ </ol>
+
+ <h3>Set up of SNMPServer machine</h3>
+ <ol>
+ <li>
+ setup network as “Bridged Adapter” -> Machine-> Settings ->Network
+
+ Install snmpd and snmp packages and tools for inspecting the
+ data available over SNMP.
+ <ol type="disc">
+ <li>
+ command <i>apt-get install snmpd snmp snmp-mibs-downloader</i>
+ </li>
+ </ol>
+ <li>
+ RECOMMENDATION! Before doing any changes to your /etc/snmp/snmpd.conf
+ file take a copy of original file.
+ <ol type="disc">
+ <li>
+ command <i>cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.orig</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Set up the snmp server to allow all other computers to access it = edit
+ snmpd.conf file.
+ <ol type="disc">
+ <li>
+ command <i>nano /etc/snmp/snmpd.conf</i>
+ (you can use different editor)
+ </li>
+ <li>
+ Check this 4 rows and make sure they look like this:<br>
+ <i># Listen for connections from the local system only<br>
+ # agentAddress udp:127.0.0.1:161<br>
+ # Listen for connections on all interfaces (both IPv4 *and* IPv6)<br>
+ agentAddress udp:161,udp6:[::1]:161</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Add a group (community) of computers we deem to be worthy of
+ accessing all data. This group will be called students = again edit
+ snmpd.conf file.
+ <ol type="disc">
+ <li>
+ rocommunity students 0.0.0.0/0
+ </li>
+ <li>
+ change 0.0.0.0./0 into correct address <i>ifconfig -a</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ OPTIONAL CONFIGURATION. Lower in the same file you can set the
+ location of the computer snmpd is running on and the name
+ of the administrator.
+ <ol type="disc">
+ <li>
+ find under # SYSTEM INFORMATION
+ </li>
+ </ol>
+ </li>
+ <li>
+ Make sure that the SNMP server reports it's uptime in seconds
+ over SNMP under NET-SNMP-EXTEND-MIB::nsExtendOutput2Table.
+ <ol type="disc">
+ <li>
+ create script upseconds containing this and save it where
+ you want:<br>
+ <i>#!/bin/bash<br>
+ uptime=$(&lt;/proc/uptime)<br>
+ seconds=${uptime%%.*}<br>
+ echo "Uptime in seconds:" $seconds<br>
+ exit 0</i>
+ </li>
+ <li>
+ don't forget to make the script runnable:<br>
+ command <i>chmod +x /your_path_to_script/upseconds</i>
+ </li>
+ <li>
+ Then edit file <i>snmpd.conf</i> and under # EXTENDING THE AGENT
+ comment all three tests and add your line of your code
+ with upsecond script. It will look like this:<br>
+ <i># extend test1 /bin/echo Hello, world!<br>
+ # extend-sh test2 echo Hello, world! ; echo Hi there ; exit 35<br>
+ # extend-sh test3 /bin/sh /tmp/shtest<br>
+ extend-sh "your_name" "your_path_to_script_upseconds"
+ </i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ You need to restart the snmp services.
+ <ol type="disc">
+ <li>
+ command <i>/etc/init.d/snmpd restart</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ You can test your configuration through localhost.
+ <ol type="disc">
+ <li>
+ command <i>snmpwalk localhost -c public -v1</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Also test the correct return of server's uptime in seconds SNMP under
+ NET-SNMP-EXTEND-MIB::nsExtendOutput2Table.
+ <ol type="disc">
+ <li>
+ command <i>snmpwalk -c students -v1 IPaddressOfServer
+ 1.3.6.1.4.1.8072.1.3.2.4.1.2</i>
+ </li>
+ <li>
+ you should get string: "Uptime in seconds: xyz"
+ </li>
+ </ol>
+ </li>
+ </ol>
+
+ <h3>Set up of SNMPClient machine</h3>
+ <ol>
+ <li>
+ Install snmpd and snmp packages.
+ <ol type="disc">
+ <li>
+ command <i>apt-get install snmpd snmp</i>
+ </li>
+ </ol>
+ <li>
+ RECOMMENDATION! Before doing any changes to your /etc/snmp/snmpd.conf
+ file take a copy of original file.
+ <ol type="disc">
+ <li>
+ command <i>cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.orig</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Set up the snmp client to allow all other computers to access it = edit
+ snmpd.conf file.
+ <ol type="disc">
+ <li>
+ command <i>nano /etc/snmp/snmpd.conf</i>
+ (you can use different editor)
+ </li>
+ <li>
+ (un)comment these four lines as below:<br>
+ <i># Listen for connections from the local system only<br>
+ # agentAddress udp:127.0.0.1:161<br>
+ # Listen for connections on all interfaces (both IPv4 *and* IPv6)<br>
+ agentAddress udp:161,udp6:[::1]:161</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Add a group (community) of computers we deem to be worthy of
+ accessing all data. This group will be called students = again edit
+ snmpd.conf file.
+ <ol type="disc">
+ <li>
+ rocommunity students 0.0.0.0/0
+ </li>
+ <li>
+ write correct network address = command <i>ifconfig -a</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ OPTIONAL CONFIGURATION. Lower in the same file you can set the
+ location of the computer snmpd is running on and the name
+ of the administrator.
+ <ol type="disc">
+ <li>
+ find under # SYSTEM INFORMATION
+ </li>
+ </ol>
+ </li>
+
+ <li>
+ You need to restart the snmp services.
+ <ol type="disc">
+ <li>
+ command <i>/etc/init.d/snmpd restart</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ You can test your configuration through localhost.
+ <ol type="disc">
+ <li>
+ command <i>snmpwalk localhost -c public -v1</i>
+ </li>
+ </ol>
+ </li>
+ <li>Create the user <i>test</i> with password <i>test</i>
+ <ol type="disc">
+ <li>
+ command <i>adduser test</i>
+ </li>
+ </ol>
+ </li>
+ <li>Login as user <i>test</i> and create program <i>upminutes</i>
+ in the home directory. This program should output the uptime of the
+ computer in minutes.
+ <ol type="disc">
+ <li>
+ command <i>nano upminutes</i> (you can use different editor)
+ </li>
+ <li>
+ add the source code:<br>
+ <i>#!/bin/bash<br>
+ uptime=$(&lt;/proc/uptime)<br>
+ uptime=${uptime%%.*}<br>
+ minutes=$(( uptime / 60 ))<br>
+ echo $minutes<br>
+ exit 0</i>
+ </li>
+ <li>
+ don't forget to make the program runnable:<br>
+ command <i>chmod +x /home/test/upminutes</i>
+ </li>
+ <li>
+ test the program (it should output the uptime of the
+ computer in minutes)<br>
+ command <i>/home/test/upminutes</i>
+ </li>
+ </ol>
+ </li>
+ <li><strong> As user <i>test</i> and create next script called
+ <i>beri.sh</i> that reads the value from the OID
+ 1.3.6.1.4.1.8072.1.3.2.4.1.2. on SNMPServer. Set it up on SNMPClient
+ in the home directory of the user test.
+ <ol type="disc">
+ <li>
+ command <i>nano beri.sh</i> (you can use different editor)
+ </li>
+ <li>
+ add the source code:<br>
+ <i>#!/bin/bash<br>
+ snmpwalk -c students -v1 IPServerAddress 1.3.6.1.4.1.8072.1.3.2.4.1.2<br>
+ exit 0</i>
+ </li>
+ <li>
+ don't forget to make the program runnable:<br>
+ command <i>chmod +x /home/test/upminutes</i>
+ you can test it with <i>./beri.sh</i>
+ </li>
+ </ol>
+ </li>
+ </ol>
+
+ <h3> Setting SimpleArbiter </h3>
+ User: tester
+ Password: test
+
+ apt-get install libsnmp-python
+ </body>
+</html>
diff --git a/tasks/snmp_agent_uptime/howtos/images/01.png b/tasks/snmp_agent_uptime/howtos/images/01.png
new file mode 100644
index 0000000..1bd01aa
--- /dev/null
+++ b/tasks/snmp_agent_uptime/howtos/images/01.png
Binary files differ
diff --git a/tasks/snmp_agent_uptime/howtos/si/index.html b/tasks/snmp_agent_uptime/howtos/si/index.html
new file mode 100644
index 0000000..f490f6c
--- /dev/null
+++ b/tasks/snmp_agent_uptime/howtos/si/index.html
@@ -0,0 +1,308 @@
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>snmp_agent_uptime</title>
+ </head>
+ <body>
+ <h1>snmp_agent_uptime</h1>
+ <h2>Namen naloge</h2>
+ <p>
+
+ </p>
+ <h2>Hitra navodila</h2>
+ <p>
+ Naloga: Postavi tri navidezne racunalnike SimpleArbiter s sliko diska simpleArbiterDhcp,SNMPServer in
+ SNMPClient.
+ Napiši program upminutes, ki bo izpisal v minutah koliko casa je racunalnik vklopljen.
+ Postavi ga na SNMPClient v domaÄŤi imenik uporabnika test z geslom test.
+ </p>
+ <p>
+ Poskrbi, da bo SNMP strežnik prek SNMP pod NET-SNMP-EXTEND-MIB::nsExtendOutput2Table sporočal, koliko časa je vklopljen v sekundah.
+ </p>
+ <p>
+ Napisi skripto, poimenovano beri.sh, ki prek SNMP prebere vrednost s streĹľnika
+ SNMPServer na OID 1.3.6.1.4.1.8072.1.3.2.4.1.4.
+ Postavi jo na SNMP klienta, v domači imenik uporabnika test z geslom test.
+ </p>
+ <h2>Navodila</h2>
+ <h3>Nastavitev VM VirtualBox-a</h3>
+ <ol>
+ <li>
+ Prenesi sledeče slike virtualk (*.vid) iz datoteke
+ z slikami virtualk računalnikov:
+ <ol type="disc">
+ <li>
+ simpleArbiterDhcp.vdi
+ </li>
+ <li>
+ neko-bash-konzolo.vdi (dvakrat), enkrat za SNMPServer
+ in drugič SNMPClient.
+ </li>
+ </ol>
+ </li>
+ <li>
+ VM VirtualBox OPOZORILO! Ce hoces uporabljati isto sliko virtualke
+ (neko-bash-konzolo.vdi) za dva navidezna racunalnika
+ (SNMPServer in SNMPClient), moras <strong>spremeniti UUID</strong>
+ ene od slik.
+ <ol type="disc">
+ <li>
+ Uporabi ta ukaz
+ <i>vboxmanage internalcommands sethduuid ime-diska.vdi</i>
+ za spreminjanje UUID (<a href="http://www.giannistsakiris.com/2009/05/06/virtualbox-how-to-change-the-uuid-of-virtual-disk-vdi/">namig</a>).
+ </li>
+ </ol>
+ </li>
+ <li>
+ Primer VM VirtualBox-a po nastavitvi.<br>
+ <img src="..\images\01.png" width="800">
+ </li>
+ </ol>
+
+ <h3>Nastavitev SNMPServer virtualke</h3>
+ <ol>
+ <li>
+ Nasnemi snmpd and snmp orodja za pregledovanje
+ podatkov, ki so no voljo preko SNMP.
+ <ol type="disc">
+ <li>
+ ukaz <i>apt-get install snmpd snmp snmp-mibs-downloader</i>
+ </li>
+ </ol>
+ <li>
+ PRIPOROCILO! Preden spreminjate vaso datoteko /etc/snmp/snmpd.conf,
+ naredite kopijo originalne datoteke.
+ <ol type="disc">
+ <li>
+ ukaz <i>cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.orig</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Nastavi snmp streznik tako, da se bodo lahko nanj povezali drugi racunalniki
+ (popravi datoteko snmpd.conf).
+ <ol type="disc">
+ <li>
+ ukaz <i>nano /etc/snmp/snmpd.conf</i>
+ (lahko uporabis drug urejevalnik besedila)
+ </li>
+ <li>
+ odkomentiraj sledece stiri vrstice:<br>
+ <i># Listen for connections from the local system only<br>
+ # agentAddress udp:127.0.0.1:161<br>
+ # Listen for connections on all interfaces (both IPv4 *and* IPv6)<br>
+ agentAddress udp:161,udp6:[::1]:161</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Dodaj skupino (community) racunalnikov, ki lahko dostopajo do vseh podatkov.
+ To skupino bomo poimenovali students (spet potrebno spremeniti datoteko)
+ snmpd.conf file.
+ <ol type="disc">
+ <li>
+ rocommunity students 0.0.0.0/0
+ </li>
+ <li>
+ napisi pravilni naslov omrezja = ukaz <i>ifconfig -a</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ DODATNA (NEOBVEZNA) KONFIGURACIJA. Nizje v isti datoteki lahko nastavis
+ lokacijo racunalnika, na katerem deluje snmp, ter ime administratorja.
+ <ol type="disc">
+ <li>
+ poisci pod # SYSTEM INFORMATION
+ </li>
+ </ol>
+ </li>
+ <li>
+ Poskrbi, da bo SNMP streznik prek SNMP pod NET-SNMP-EXTEND-MIB::nsExtendOutpucd
+ k t2Table sporocal, koliko casa je vklopljen v sekundah.
+ <ol type="disc">
+ <li>
+ ustvari skripto upseconds, v kateri je zapisano sledece:<br>
+ <i>#!/bin/bash<br>
+ uptime=$(&lt;/proc/uptime)<br>
+ seconds=${uptime%%.*}<br>
+ echo "Uptime in seconds:" $seconds<br>
+ exit 0</i><br>
+ skripto nato shrani kjerkoli hoces
+ </li>
+ <li>
+ ne pozabi skripti dodelti pravic, da jo lahko zaganjamo:<br>
+ ukaz <i>chmod +x /pot_do_skripte/upseconds</i>
+ </li>
+ <li>
+ Nato uredi datoteko <i>snmpd.conf</i> in pod # EXTENDING THE AGENT
+ zakomentiraj vse tri teste ter dodaj svojo skripto upseconds.
+ Zgledati bi moralo nekako tako:<br>
+ <i># extend test1 /bin/echo Hello, world!<br>
+ # extend-sh test2 echo Hello, world! ; echo Hi there ; exit 35<br>
+ # extend-sh test3 /bin/sh /tmp/shtest<br>
+ extend-sh "ime_testa" "pot_to_skripte_upseconds"
+ </i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Potrebno je ponovno zagnati snmp storitev.
+ <ol type="disc">
+ <li>
+ ukaz <i>/etc/init.d/snmpd restart</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Lahko testiras svoje nastavitve preko localhost-a.
+ <ol type="disc">
+ <li>
+ ukaz <i>snmpwalk localhost -c public -v1</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Stestiraj tudi, ali SNMP vrne pravilni cas delovanja (uptime) v sekundah
+ pod NET-SNMP-EXTEND-MIB::nsExtendOutput2Table.
+ <ol type="disc">
+ <li>
+ ukaz <i>snmpwalk -c students -v1 IPnaslovStreznika
+ 1.3.6.1.4.1.8072.1.3.2.4.1.2</i>
+ </li>
+ <li>
+ moral bi vrniti taksen string: "Uptime in seconds: xyz"
+ </li>
+ </ol>
+ </li>
+ </ol>
+
+ <h3>Nastavitev SNMPClient virtualke</h3>
+ <ol>
+ <li>
+ Nasnemi snmpd and snmp paketa.
+ <ol type="disc">
+ <li>
+ ukaz <i>apt-get install snmpd snmp</i>
+ </li>
+ </ol>
+ <li>
+ PRIPOROCILO! Preden spreminjate vaso datoteko /etc/snmp/snmpd.conf,
+ naredite kopijo originalne datoteke.
+ <ol type="disc">
+ <li>
+ ukaz <i>cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.orig</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Nastavi snmp streznik tako, da se bodo lahko nanj povezali drugi racunalniki
+ (popravi datoteko snmpd.conf).
+ <ol type="disc">
+ <li>
+ ukaz <i>nano /etc/snmp/snmpd.conf</i>
+ (lahko uporabis drug urejevalnik besedila)
+ </li>
+ <li>
+ odkomentiraj sledece stiri vrstice:<br>
+ <i># Listen for connections from the local system only<br>
+ # agentAddress udp:127.0.0.1:161<br>
+ # Listen for connections on all interfaces (both IPv4 *and* IPv6)<br>
+ agentAddress udp:161,udp6:[::1]:161</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Dodaj skupino (community) racunalnikov, ki lahko dostopajo do vseh podatkov.
+ To skupino bomo poimenovali students (spet potrebno spremeniti datoteko)
+ snmpd.conf file.
+ <ol type="disc">
+ <li>
+ rocommunity students 0.0.0.0/0
+ </li>
+ <li>
+ napisi pravilni naslov omrezja = ukaz <i>ifconfig -a</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ DODATNA (NEOBVEZNA) KONFIGURACIJA. Nizje v isti datoteki lahko nastavis
+ lokacijo racunalnika, na katerem deluje snmp, ter ime administratorja.
+ <ol type="disc">
+ <li>
+ poisci pod # SYSTEM INFORMATION
+ </li>
+ </ol>
+ </li>
+
+ <li>
+ Potrebno je ponovno zagnati snmp storitev.
+ <ol type="disc">
+ <li>
+ ukaz <i>/etc/init.d/snmpd restart</i>
+ </li>
+ </ol>
+ </li>
+ <li>
+ Lahko testiras svoje nastavitve preko localhost-a.
+ <ol type="disc">
+ <li>
+ ukaz <i>snmpwalk localhost -c public -v1</i>
+ </li>
+ </ol>
+ </li>
+ <li>Ustvari uporabnika <i>test</i> z geslom <i>test</i>
+ <ol type="disc">
+ <li>
+ ukaz <i>adduser test</i>
+ </li>
+ </ol>
+ </li>
+ <li>Prijavi se kot uporabnik <i>test</i> ter naredi skripto <i>upminutes</i>
+ v domacem direktoriju. Ta skripta naj izpisuje cas delovanja racunalnika (uptime) v minutah.
+ <ol type="disc">
+ <li>
+ ukaz <i>nano upminutes</i> (lahko uporabis drug urejevalnik besedila)
+ </li>
+ <li>
+ dodaj sledeco kodo:<br>
+ <i>#!/bin/bash<br>
+ uptime=$(&lt;/proc/uptime)<br>
+ uptime=${uptime%%.*}<br>
+ minutes=$(( uptime / 60 ))<br>
+ echo $minutes<br>
+ exit 0</i>
+ </li>
+ <li>
+ ne pozabi skripti dodelti pravic, da jo lahko zaganjamo:<br>
+ ukaz <i>chmod +x /pot_do_skripte/upminutes</i>
+ </li>
+ <li>
+ stestiraj skripto (izpisovati bi morala cas delovanja racunalnika (uptime) v minutah)<br>
+ ukaz <i>/home/test/upminutes</i>
+ </li>
+ </ol>
+ </li>
+ <li>Kot uporabnik <i>test</i> naredi se eno skripto <i>beri.sh</i>m ki bere
+ vrednosti od OID 1.3.6.1.4.1.8072.1.3.2.4.1.2.
+ na SNMPServer. Shrani jo na SNMPClient v domac direktorij uporabnika test.
+ <ol type="disc">
+ <li>
+ ukaz <i>nano beri.sh</i> (lahko uporabis drug urejevalnik besedila)
+ </li>
+ <li>
+ dodaj kodo:<br>
+ <i>#!/bin/bash<br>
+ snmpwalk -c students -v1 IPnaslovStreznika 1.3.6.1.4.1.8072.1.3.2.4.1.2<br>
+ exit 0</i>
+ </li>
+ <li>
+ ne pozabi skripti dodelti pravic, da jo lahko zaganjamo:<br>
+ ukaz <i>chmod +x /pot_do_skripte/upminutes</i>
+ </li>
+ </ol>
+ </li>
+ </ol>
+
+ </body>
+</html>
diff --git a/tasks/snmp_agent_uptime/task.py b/tasks/snmp_agent_uptime/task.py
new file mode 100644
index 0000000..919fcb4
--- /dev/null
+++ b/tasks/snmp_agent_uptime/task.py
@@ -0,0 +1,224 @@
+# kpov_util should be imported by add_assignment.py
+
+# TODO: finish this.
+instructions = {
+ 'si': '''\
+<p>
+Postavi tri navidezne računalnike: <em>SimpleArbiter</em>, <em>SNMPServer</em> in <em>SNMPClient</em>.
+
+<p>
+Napiši program <code>upminutes</code>, ki bo izpisal v minutah, koliko časa je racunalnik vklopljen. Postavi ga na <em>SNMPClient</em> v domači imenik uporabnika <code>test</code> z geslom <code>test</code>.
+
+<p>
+Poskrbi, da bo strežnik SNMP pod OID
+
+<pre><code>{{SNMP_UPTIME_OID}}</code></pre>
+
+<p>
+sporočal, koliko časa je vklopljen v sekundah.
+
+<p>
+Napiši skripto, poimenovano <code>beri.sh</code>, ki prek SNMP prebere vrednost s <em>simpleArbiterDhcpGWSNMP</em> na OID
+
+<pre><code>{{SNMP_CLIENT_OID}}</code></pre>
+
+<p>
+kot član skupnosti <code>testers</code>. Postavi jo na <em>SNMPClient</em>, v domači imenik uporabnika <code>test</code>. Poskrbi, da bodo podatki na SNMPServer dostopni za skupino (angl. <em lang="en">community</em>) <code>studentje</code>.
+''',
+ 'en': '''\
+<p>
+Set up three virtual computers: <em>SimpleArbiter</em>, <em>SNMPServer</em> and <em>SNMPClient</em>.
+
+<p>
+Write a program called <code>upminutes</code>. This program should output the uptime of the computer in minutes. Set it up on <em>SNMPClient</em> in the home directory of the user <code>test</code> with the password <code>test</code>.
+
+<p>
+Make sure that the SNMP server reports its uptime in seconds over SNMP under OID
+
+<pre><code>{{SNMP_UPTIME_OID}}</code></pre>
+
+<p>
+Write a script called <code>beri.sh</code> that reads the value from the OID
+
+<pre><code>{{SNMP_CLIENT_OID}}</code></pre>
+
+<p>
+on <em>simpleArbiterDhcpGWSNMP</em> as a member of the community <code>testers</code>. Set it up on <em>SNMPClient</em> in the home directory of the user <code>test</code>. Make all the data available over SNMP readable by the community <code>studentje</code>.
+''',
+}
+
+computers = {
+ 'SNMPClient': {
+ 'disks': [
+ { 'name': 'student-SNMPClient',
+
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'SNMPServer': {
+ 'disks': [
+ { 'name': 'student-SNMPServer',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGWSNMP',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'SNMP_VALUE': {'descriptions': {'si': 'Vrednost, dostopna prek SNMP', 'en': 'The value available over SNMP'}, 'w': False, 'public':False, 'type': 'short', 'generated': True},
+ 'SNMP_UPTIME_OID': {'descriptions': {'si': 'SNMP_UPTIME_OID (za uptime)', 'en': 'SNMP_UPTIME_OID (for the uptime)'}, 'w': False, 'public':True, 'type': 'str', 'generated': True},
+ 'SNMP_CLIENT_OID': {'descriptions': {'si': 'SNMP_CLIENT_OID, ki naj ga klient bere', 'en':'The OID that the client should read'}, 'w': False, 'public':True, 'type': 'OID', 'generated': True},
+ 'SERVER_IP': {'descriptions': {'si': 'IP SNMP strežnika', 'en':'IP of the SNMP server'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+ 'CLIENT_IP': {'descriptions': {'si': 'IP SNMP klienta', 'en': 'IP of the SNMP client'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
+
+}
+
+def task(SERVER_IP, CLIENT_IP, SNMP_UPTIME_OID, SNMP_CLIENT_OID):
+ #<== Aleksander Fujs 6310020 ==>
+ # TODO popravi IPje
+ import netsnmp
+ import paramiko
+ from paramiko import SSHClient
+ return_results = {}
+
+ client = SSHClient()
+ client.load_system_host_keys()
+ client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+ client.connect(SERVER_IP, username='student', password='vaje')
+ stdin, stdout, stderr = client.exec_command('uptime=$(</proc/uptime); uptime=${uptime%%.*}; echo $uptime')
+ return_results['server_uptime'] = stdout.read()
+
+ try:
+ session = netsnmp.Session(DestHost=SERVER_IP, Version=2, Community='studentje')
+ # results_objs = netsnmp.VarList(netsnmp.Varbind(SNMP_UPTIME_OID)) #117.112.116.105.109.101 <-uptime
+ results_objs = netsnmp.VarList(netsnmp.Varbind('.1.3.6.1.4.1.8072.1.3.2.4.1.2')) #117.112.116.105.109.101 <-uptime
+ session.walk(results_objs)
+ result_list = []
+ for result in results_objs:
+ result_list.append('{}.{}: {}'.format(
+ result.tag, result.iid, result.val))
+ return_results['server_OID'] = "\n".join(result_list)
+ except Exception as exception_error:
+ # Check for errors and print out results
+ print(('ERROR: Occurred during SNMPget for OID %s from %s: '
+ '(%s)') % (SNMP_UPTIME_OID, CLIENT_IP, exception_error))
+ sys.exit(2)
+
+ client.connect(CLIENT_IP, username='test', password='test')
+ stdin, stdout, stderr = client.exec_command('uptime=$(</proc/uptime); uptime=${uptime%%.*}; echo $(( uptime ))')
+ return_results['client_uptime'] = stdout.read()
+ # zakaj bi morala biti ravno bash skripta?
+ stdin, stdout, stderr = client.exec_command('/home/test/upminutes')
+ #TODO preverit da ni v skripti hardcodan
+ return_results['client_script'] = stdout.read()
+
+ stdin, stdout, stderr = client.exec_command('/home/test/beri.sh')
+ return_results['client_script2'] = stdout.read()
+ #TODO add 3 part of assigement
+ return return_results
+ #<== Aleksander Fujs 6310020 ==>
+
+
+def gen_params(user_id, params_meta):
+ import random
+ params = dict()
+ r = random.Random(user_id)
+ # You can also create an OID creation function in kpov_util.
+ # this should probably return params_meta
+
+ #<== Aleksander Fujs 6310020 ==>
+ params['SNMP_VALUE'] = kpov_util.alnum_gen(r, 64)
+ params['SNMP_UPTIME_OID'] = 'NET-SNMP-EXTEND-MIB::nsExtendOutLine."{}".1'.format(
+ kpov_util.hostname_gen(r))
+ params['SNMP_CLIENT_OID'] = '1.3.6.1.4.1.8072.2.9999.9999.{}'.format(
+ r.randint(0, 255))
+ #<== Aleksander Fujs 6310020 ==>
+
+ return params
+
+def task_check(results, params):
+ #TODO improve regex
+ import re
+ score = 0
+ hints = []
+ client_script_uptime = int(results['client_script'].strip())
+ client_uptime = int(results['client_uptime'].strip())
+ d = client_uptime - client_script_uptime*60
+ if d >= 0 and d < 62:
+ score += 3
+ else:
+ hints += ["client uptime script output wrong."]
+ server_uptime = int(results['server_uptime'].strip())
+ lines = results['server_OID'].split('\n')
+ unique_part_start = params['SNMP_UPTIME_OID'].find('"')
+ unique_part_end = params['SNMP_UPTIME_OID'].find('"', unique_part_start+1)
+ unique_part = params['SNMP_UPTIME_OID'][unique_part_start+1:unique_part_end]
+ server_oid = 'iso.3.6.1.4.1.8072.1.3.2.4.1.2.{}.'.format(len(unique_part))
+ server_oid += '.'.join([str(ord(i)) for i in unique_part]) + '.1.'
+ found_uptime = False
+ for line in lines:
+ try:
+ oid, uptime_s = line.split(':')
+ d = server_uptime - int(uptime_s.strip())
+ if oid.strip() == server_oid and d >= -2 and d <= 5:
+ found_uptime = True
+ break
+ except Exception as e:
+ pass
+ if len(lines) <= 50 and found_uptime:
+ score += 3
+ else:
+ hints += ["Uptime not found in server's MDB"]
+ if results['client_script2'].find(params['SNMP_VALUE']) >= 0:
+ score += 4
+ else:
+ hints += ["beri.sh not working properly"]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+# d = templates['simpleArbiterDhcp']
+ prog = """#!/usr/bin/python
+import sys
+action = sys.argv[1]
+oid = sys.argv[2]
+
+foo_oid = ".{oid}"
+foo_oid_start = foo_oid[:foo_oid.rfind('.')]
+foo_oid_end = foo_oid[len(foo_oid_start)+1:]
+oid_end = oid[len(foo_oid_start)+1:]
+oid_start = oid[:len(foo_oid_start)]
+
+if action == '-n' and (
+ (oid_start == foo_oid_start) and (
+ (len(oid_end) == 0) or (int(oid_end) < int(foo_oid_end))
+ )
+ ):
+ oid = foo_oid
+
+if action != '-s' and oid == foo_oid:
+ print foo_oid
+ print "string"
+ print "{val}"
+""".format(oid = task_params['SNMP_CLIENT_OID'], val = task_params['SNMP_VALUE'])
+ templates['simpleArbiterDhcpGWSNMP'].write('/usr/local/bin/snmpext.py', prog)
+ templates['simpleArbiterDhcpGWSNMP'].chmod(0o755, '/usr/local/bin/snmpext.py')
+ write_default_config(templates['simpleArbiterDhcpGWSNMP'], global_params)
diff --git a/tasks/snmp_alarms_interfaces/task.py b/tasks/snmp_alarms_interfaces/task.py
new file mode 100644
index 0000000..03d4509
--- /dev/null
+++ b/tasks/snmp_alarms_interfaces/task.py
@@ -0,0 +1,107 @@
+# kpov_util should be imported by add_assignment.py
+
+instructions = {
+ 'si':"""
+<pre>Postavite tri računalnike - SimpleArbiterSNMP s sliko diska simpleArbiterSNMP, ServerSNMP s sliko
+diska serverSNMP ter SNMPClient.
+
+Na SNMPClient ustvarite uporabnika test z geslom test. V datoteko /home/test/alarmi zapišite
+vse IP in vse OID, s katerih po SNMP prihajajo alarmi. Za vsak alarm zapišite eno vrstico,
+v kateri bosta najprej IP, nato OID, ločena s presledkom.
+
+V datoteko /home/test/vmesniki vpišite imena vseh omrežnih vmesnikov, ki jih prek SNMP dobite na
+ServerSNMP.</pre>
+"""
+}
+
+computers = {
+ 'maliNetworkManager': {
+ 'disks': [
+ { 'name': 'maliNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'maliBrezNetworkManager': {
+ 'disks': [
+ { 'name': 'maliBrezNetworkManager',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcp',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+params_meta = {
+ 'IP_NM': {'descriptions': {'si': 'Naslov maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'DNS_NM': {'descriptions': {'si': 'DNS za maliNetworkManager'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+ 'IP_static': {'descriptions': {'si': 'Naslov maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+ 'DNS_static': {'descriptions': {'si': 'DNS za maliBrezNetworkManager'}, 'w': False, 'public': True, 'type': 'IP', 'generated': True},
+}
+
+def task(IP_NM, DNS_NM, IP_static, DNS_static):
+ from pexpect import pxssh
+ import pexpect
+ results = dict()
+ peer_user = 'student'
+ peer_passwd = 'vaje'
+ sA = pxssh.pxssh()
+ sB = pxssh.pxssh()
+ sA.login(IP_NM, peer_user, peer_passwd)
+ sB.login(IP_static, peer_user, peer_passwd)
+ # sA
+ # make sure NM is not handling eth0
+ results['NM_nmcli'] = sA.run('nmcli d')
+ results['NM_nslookup'] = sA.run('nslookup www.arnes.si')
+ # sB
+ # check whether NM is handling eth0
+ results['static_nmcli'] = sB.run('nmcli d')
+ results['static_nslookup'] = sB.run('nslookup www.arnes.si')
+ sA.logout()
+ sB.logout()
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ # IP_NM, DNS_NM, IP_static, DNS_static)
+ dns_servers = ['193.2.1.66', '193.2.1.72', '8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220']
+ net = kpov_util.IPv4_subnet_gen(r, '172.23.128.0/18', 24)
+ params['DNS_NM'] = r.choice(dns_servers)
+ params['IP_NM'], params['IP_static'] = kpov_util.IPv4_addr_gen(r, net, 2)
+ params['DNS_static'] = r.choice(dns_servers)
+ return params
+
+def task_check(results, params):
+ import re
+ score = -9
+ hints = []
+ if results['NM_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_NM'])) > -1:
+ score += 3
+ if results['static_nslookup'].find('Server:\t\t{0}\r'.format(params['DNS_static'])) > -1:
+ score += 3
+ if re.search(r'eth0 +802-.*connected', results['NM_nmcli']):
+ score += 2
+ if not re.search(r'eth0 +802-.*connected', results['static_nmcli']):
+ score += 2
+ score = 0
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiterDhcp'], global_params)
diff --git a/tasks/vlc_stream_rtp/howtos/en/index.html b/tasks/vlc_stream_rtp/howtos/en/index.html
new file mode 100644
index 0000000..c9e2714
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/en/index.html
@@ -0,0 +1,94 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+
+<h2> Summary </h1>
+
+<ol>
+ <li>Set up a virtual machine</li>
+ <li>Install VLC</li>
+ <li>Create RTP video stream</li>
+ <li>Make sure the stream is accessible from the internet</li>
+</ol>
+
+ <h2>Instructions</h1>
+
+ <ol>
+ <li>
+ <h4>Set up a virtual machine </h3>
+ <p> Use disk simpleArbiter. You can get it <a href="http://polz.si/media/uploads/kpov/virtualke/">here</a>. </p>
+ </li>
+
+ <li>
+ <h4>Install VLC</h3>
+ <p>
+ In file <code>/etc/apt/sources.list</code> replace <code>wheezy</code> with
+ <code>testing</code> or if missing, add rows:
+ </p>
+ <p>
+ <code>
+ deb http://ftp.at.debian.org/debian wheezy main contrib non-free <br>
+ deb-src http://ftp.at.debian.org/debian wheezy main contrib non-free
+ </code>
+ </p>
+ <img alt="slika-01" src="../images/1.png" style="width: 640px;" />
+ <p>
+ Check for updates and install VLC with the following commands:
+ </p>
+ <p>
+ <code>
+ apt-get update <br>
+ apt-get install vlc
+ </code>
+ </p>
+ </li>
+
+ <li>
+ <h4>Create a new stream </h3>
+
+ <p>
+ Open VLC. In Media menu select Stream.
+ </p>
+ <img src="../images/stream_menu.png" style="width: 640px;" alt="menu">
+ <p>
+ Here we choose stream source. This can be a file, a network stream or a capture device. <br>
+ For this excercise, add one or more video file by clicking <i>Add ...</i> Continue with a click on button Stream.
+ </p>
+ <img src="../images/playlist.PNG" style="width: 640px;" alt="stream source">
+ <p>
+ We must also choose the stream destination. For this excercise, choose RTP/MPEG Transport Stream and click Add.
+ You can configure multiple destinations simultaneously.
+ </p>
+ <p>
+ Configure destination settings. Enter address and stream name.
+ </p>
+ <img src="../images/stream_output.PNG" style="width: 640px;" alt="stream destination">
+ <p>
+ Next, we can set transcoding, encapsulation, audio and video codecs and also subtitles. When you finish, click Save and Next.
+ </p>
+ <img src="../images/stream_transcoding.PNG" style="width: 640px;" alt="stream settings">
+ <p>
+ In the last step, it is important to check option Stream all elementary streams.
+ In the text area, we can see the string that can be used to run the stream from a command line.
+ This is useful if you want to run stream from a computer without graphic interface.
+ </p>
+ <img src="../images/stream_finish.PNG" style="width: 640px;">
+ </li>
+
+ <li>
+ <h4>Open stream </h3>
+ <p>
+ We can now play the stream from another device using VLC.
+ </p>
+ <img src="../images/stream_open.PNG" style="width: 640px;" alt="play stream">
+ </li>
+</ol>
+
+</body>
+
+</html> \ No newline at end of file
diff --git a/tasks/vlc_stream_rtp/howtos/images/1.png b/tasks/vlc_stream_rtp/howtos/images/1.png
new file mode 100644
index 0000000..903be70
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/1.png
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/images/playlist.PNG b/tasks/vlc_stream_rtp/howtos/images/playlist.PNG
new file mode 100644
index 0000000..b815098
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/playlist.PNG
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/images/stream_finish.PNG b/tasks/vlc_stream_rtp/howtos/images/stream_finish.PNG
new file mode 100644
index 0000000..f429a9b
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/stream_finish.PNG
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/images/stream_menu.png b/tasks/vlc_stream_rtp/howtos/images/stream_menu.png
new file mode 100644
index 0000000..01f52c6
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/stream_menu.png
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/images/stream_open.PNG b/tasks/vlc_stream_rtp/howtos/images/stream_open.PNG
new file mode 100644
index 0000000..772ffe8
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/stream_open.PNG
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/images/stream_output.PNG b/tasks/vlc_stream_rtp/howtos/images/stream_output.PNG
new file mode 100644
index 0000000..c3dc2a7
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/stream_output.PNG
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/images/stream_transcoding.PNG b/tasks/vlc_stream_rtp/howtos/images/stream_transcoding.PNG
new file mode 100644
index 0000000..1fbc9f3
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/images/stream_transcoding.PNG
Binary files differ
diff --git a/tasks/vlc_stream_rtp/howtos/si/index.html b/tasks/vlc_stream_rtp/howtos/si/index.html
new file mode 100644
index 0000000..c94044b
--- /dev/null
+++ b/tasks/vlc_stream_rtp/howtos/si/index.html
@@ -0,0 +1,93 @@
+<html>
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=utf-8">
+</head>
+
+
+<body><font face="Georgia, Times New Roman, Times, serif">
+
+<h2> Naloga na hitro </h1>
+
+<ol>
+ <li>Postavi navidezni računalnik</li>
+ <li>Naloži VLC</li>
+ <li>Ustvari RTP video tok</li>
+ <li>Poskrbi, da bo tok dostopen na internetu</li>
+</ol>
+
+ <h2>Navodila</h1>
+
+ <ol>
+ <li>
+ <h4>Postavi navidezni računalnik </h3>
+ <p> Uporabi disk simpleArbiter. Dobiš ga lahko <a href="http://polz.si/media/uploads/kpov/virtualke/">tu</a>. </p>
+ </li>
+
+ <li>
+ <h4>Naloži VLC </h3>
+ <p>
+ V <code>/etc/apt/sources.list</code> v spodnjih vrsticah zamenjaj <code>wheezy</code> z
+ <code>testing</code> oziroma dodaj vrstice če niso napisane:
+ </p>
+ <p>
+ <code>
+ deb http://ftp.at.debian.org/debian wheezy main contrib non-free <br>
+ deb-src http://ftp.at.debian.org/debian wheezy main contrib non-free
+ </code>
+ </p>
+ <img alt="slika-01" src="../images/1.png" style="width: 640px;" />
+ <p>
+ Poglej za posodobitve in nato naloži VLC z naslednjimi ukazi:
+ </p>
+ <p>
+ <code>
+ apt-get update <br>
+ apt-get install vlc
+ </code>
+ </p>
+ </li>
+
+ <li>
+ <h4>Ustvari nov tok </h3>
+
+ <p>
+ Odpri VLC. V meniju Media izberi Stream.
+ </p>
+ <img src="../images/stream_menu.png" style="width: 640px;" alt="Meni">
+ <p>
+ V oknu "Open Media" izberemo vir toka. Ta je lahko datoteka, že obstoječ omrežni tok ali pa snemalne naprave. <br>
+ Za namen te naloge lahko z klikom na gumb <i>Add ...</i> dodamo eno ali več video datotek. Nadaljujemo z klikom na Stream.
+ </p>
+ <img src="../images/playlist.PNG" style="width: 640px;" alt="Vir toka">
+ <p>
+ Določiti moramo tudi destinacijo toka. Za to nalogo izberemo RTP/MPEG Transport Stream in kliknemo Add.
+ Možno je nastaviti več destinacij hkrati.
+ </p>
+ <p>
+ Nato izpolnimo nastavitve destinacije z naslovom in imenom toka.
+ </p>
+ <img src="../images/stream_output.PNG" style="width: 640px;" alt="Destinacija toka">
+ <p>
+ V naslednjem koraku lahko nastavimo kodiranje, enkapsulacijo, avdio in video nastavitve ter podnapise.
+ </p>
+ <img src="../images/stream_transcoding.PNG" style="width: 640px;" alt="Nastavitve Toka">
+ <p>
+ V zadnjem koraku je pomembno obkljukati možnost Stream all elementary streams.
+ V spodnjem tekstovnem polju dobimo niz, ki ga lahko uporabimo za zagon toka iz ukazne vrstice.
+ </p>
+ <img src="../images/stream_finish.PNG" style="width: 640px;">
+ </li>
+
+ <li>
+ <h4>Odpri tok </h3>
+ <p>
+ Na drugem računalniku lahko ustvarjen video tok predvajamo z VLC.
+ </p>
+ <img src="../images/stream_open.PNG" style="width: 640px;" alt="Predvajanje toka">
+ </li>
+</ol>
+
+</body>
+
+</html> \ No newline at end of file
diff --git a/tasks/vlc_stream_rtp/task.py b/tasks/vlc_stream_rtp/task.py
new file mode 100644
index 0000000..427fc0e
--- /dev/null
+++ b/tasks/vlc_stream_rtp/task.py
@@ -0,0 +1,110 @@
+# kpov_util should be imported by add_assignment.py
+
+# Postavi nek film na Internet tako, da ga bodo lahko ostali videli.
+# TODO: finish this
+
+instructions = {
+ 'si': '''\
+<p>
+Postavi navidezni računalnik <em>SimpleArbiter</em> in <em>StudentVLC</em>. Poskrbi, da bosta na istem omrežju, od koder bosta imela dostop tudi do interneta.
+
+<p>
+Na <em>StudentVLC</em> posodobi datoteko <code>/etc/apt/sources.list</code>, preveri posodobitve in naloži VLC.
+
+<p>
+Posnemi ali kako drugače ustvari film ter poskrbi, da bo film dostopen na lokalnem omrežju prek RTP z imenom toka <code>{{TOK}}</code> na naslovu <code>{{NASLOV}}</code>, vrata <code>{{PORT}}</code>. Računaj, da bodo film lahko videli tvoji sošolci. Kršenje avtorskih pravic je pri reševanju te naloge strogo prepovedano.
+''',
+ 'en': '''\
+<p>
+Set up a virtual computer called <em>SimpleArbiter</em> using the simpleArbiter disk and
+a virtual computer called <em>StudentVLC</em> using the student-VLC disk. Make sure they
+are on the same network and that they have access to the Internet.
+
+<p>
+On StundentVLC, update /etc/apt/sources.list, check the for updates and install VLC.
+
+<p>
+Record or otherwise create a movie and make sure the movie is avaliable on your local network via RTP with the name of the stream <code>{{TOK}}</code> at the address <code>{{NASLOV}}</code> on port <code>{{PORT}}</code>. Take into account that the movie may be seen by your classmates. Copyright infrigement while solving this task is strictly prohibited.
+''',
+}
+
+computers = {
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiter',
+ },
+ ],
+ 'network_interfaces': [{'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ },
+ 'StudentVLC': {
+ 'disks': [
+ { 'name': 'student-VLC',
+ },
+ ],
+ 'network_interfaces': [{'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+
+}
+
+networks = { 'test-net': {'public': True} }
+
+params_meta = {
+ 'NASLOV': {'descriptions': {'si': 'RTP multicast IP naslov'}, 'w': False, 'public':True, 'type': 'stream_name', 'generated': True},
+ 'PORT': {'descriptions': {'si': 'RTP VRATA'}, 'w': False, 'public':True, 'type': 'port', 'generated': True},
+ 'TOK': {'descriptions': {'si': 'Naslov (ime) toka'}, 'w': False, 'public':True, 'type': 'IP', 'generated': True},
+}
+
+def task(NASLOV, TOK):
+ import pexpect
+ results = dict()
+ results['ps'] = pexpect.run('ps xa')
+ results['tcpdump_hex'] = pexpect.run('sudo /usr/sbin/tcpdump -x -c 2 dst host 239.255.255.255 and port 9875'.format(NASLOV))
+ results['tcpdump'] = pexpect.run('sudo /usr/sbin/tcpdump -c 8 dst host {}'.format(NASLOV))
+ return results
+
+def gen_params(user_id, params_meta):
+ params = dict()
+ r = random.Random(user_id)
+ net = kpov_util.IPv4_net_gen(r, min_hosts = 16,
+ local=True, multicast=True)
+ params['NASLOV'] = kpov_util.IPv4_addr_gen(r, net, 1)[0]
+ params['PORT'] = str(r.randint(5000, 6000))
+ params['TOK'] = kpov_util.hostname_gen(r)
+ return params
+
+def task_check(results, params):
+ import re
+ score = 0
+ hints = []
+ p1_s = ""
+ sname = ""
+ try:
+ packs = results['tcpdump_hex'].split('> 239.255.255.255.9875: UDP, length')
+ p1 = packs[1]
+ p1_l = p1.split('\n')
+ p1_d = p1_l[1:-1]
+ p1_s = ""
+ for i in p1_d:
+ p1_s = p1_s + "".join([j.strip() for j in i.split(' ')[1:]])
+ sname = "".join([hex(ord(i))[2:] for i in params['TOK']])
+ except:
+ hints.append("problem parsing RTP stream capture result")
+ if p1_s.find(sname) > 2:
+ score += 5
+ else:
+ hints.append("stream name not found in stream announcement")
+ s = "IP [^ ]* > {}.{}: UDP, length [0-9]+".format(
+ re.escape(params['NASLOV']),
+ params['PORT'])
+ if re.search(s, results['tcpdump']):
+ score += 5
+ else:
+ hints.append("RTP stream not detected in " + results['tcpdump'])
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ write_default_config(templates['simpleArbiter'], global_params)