Eksamen høst 2003 Operativsystemer og UNIX
Les nøye gjennom oppgavene før du begynner og pass på å besvare alle spørsmålene. Alle trykte og skrevne hjelpemidler er tillatt. Oppgavene vil ikke bli vektlagt likt ved sensur. En sannsynlig fordeling er at oppgave 1 teller 10%, oppgave 2 teller 35%, oppgave 3, 20%, oppgave 4, 15% og 5 teller 20%. De som ønsker det kan besvare oppgavene eller deler av oppgavene på engelsk. Sett gjerne egne forutsetninger dersom du synes oppgaveteksten er uklar. Beskriv forutsetningene og løs oppgaven utifra dem.
NB! Tekstens apostrofer: ` er en liten \ mens ' er en liten /

Oppgave 1

I denne oppgaven skal du i delspørsmål a) til d) løse problemet ved å angi en kommando på en linje, slik du ville ha tastet den inn til bash på en Linux-maskin fra tastaturet (du svarer for eksempel mkdir kat hvis du blir spurt: Opprett en katalog med navn kat).

a) Gi en kommando som flytter deg til katalogen /usr/bin.

b) Gi en kommando som kopierer alle filer i katalogen du står i til www i din hjemmekatalog.

c) Finn ut hvilke kataloger som er i din $PATH.

d) Du leser en webside på gnu.org. Finn ut hvilke gateways de pakkene du sender ut er innom på veien til gnu.org. gateways pakker som du sender til gnu.org er innom på veien.

e) Hva blir output av kommandoen echo "`dirname /usr/bin/emacs`/`basename /usr/bin/emacs`"

f) $ man awk gir blant annet:

Records and fields 
       Records are read in one at a time, and stored in the
       variable $0. The record is split into fields which are
       stored in $1, $2, ..., $NF.  The built-in variable NF is
       set to the number of fields.
Gitt følgende:
$ ls -l /usr/bin/emacs
lrwxrwxrwx    1 root     root           23 Jan 22  2003 /usr/bin/emacs -> /etc/alternatives/emacs
Hva blir output fra kommandoen
ls -l /usr/bin/emacs | awk '{print $NF}'

g)

$ dir="~/deleted"
$ echo $dir
~/deleted
$ cd ~/deleted
$ cd $dir
bash: cd: ~/deleted: No such file or directory
Forklar hvorfor cd ~/deleted går bra mens cd $dir feiler.

Oppgave 2

a) Lag et bash-script med navn where som tar ett og bare ett argument og som ellers avslutter med en feilmelding. Scriptet skal tolke argumentet som et programnavn og finne ut om det ligger et kjørbart program i $PATH med dette navnet. Hvis det gjør det skal det skrive ut full path til programmet og avslutte letingen. Hvis argumentet ikke er et program i $PATH skal ingen ting skrives ut.

b) På et Linux-system forekommer det ofte at man må gå igjennom mange lag med linker for å finne ut hvilket program som egentlig kjøres når man gir en kommando. Ønsker man for eksempel å finne ut hvilket program som startes når man kjører emacs, kan man starte letingen med where-scriptet i forrige deloppgave. Det kan føre til følgende leteaksjon på maskinen cube:

$ where emacs
/usr/bin/emacs
$ ls -l /usr/bin/emacs
lrwxrwxrwx    1 root     root           23 Jan 22  2003 /usr/bin/emacs -> /etc/alternatives/emacs
$ ls -l /etc/alternatives/emacs
lrwxrwxrwx    1 root     root           16 May 30  2003 /etc/alternatives/emacs -> /usr/bin/emacs21
$ ls -l /usr/bin/emacs21
lrwxrwxrwx    1 root     root           10 Jan 22  2003 /usr/bin/emacs21 -> emacs-21.2
$ ls -l /usr/bin/emacs21.2
-rwxr-xr-x    1 root     root      3978292 Mar 22  2002 /usr/bin/emacs-21.2
Legg merke til at full path måtte settes før emacs-21.2 i den siste ls-kommandoen. Dette er tidkrevende og din oppgave går ut på å skrive et script delink som gjør dette automatisk. Anvendes delink/usr/bin/emacs, skal det søke nedover i linkene til det finner det underliggende programmet og gjøre en ls -l til programmet gitt med full path. Underveis skal linkene som besøkes listes slik:
$ delink /usr/bin/emacs
lrwxrwxrwx    1 root     root           23 Jan 22  2003 /usr/bin/emacs -> /etc/alternatives/emacs
lrwxrwxrwx    1 root     root           16 May 30  2003 /etc/alternatives/emacs -> /usr/bin/emacs21
lrwxrwxrwx    1 root     root           10 Jan 22  2003 /usr/bin/emacs21 -> emacs-21.2
-rwxr-xr-x    1 root     root      3978292 Mar 22  2002 /usr/bin/emacs-21.2
Legg merke til at i 3. line av output fra delink står emacs-21.2 linken uten full path. Pass på at scriptet takler dette når det søker nedover i linkene.

Hvis argumentet til delink er en fil skal bare ls -l for denne filen med full path skrives ut:

$ delink /usr/bin/perl
-rwxr-xr-x    3 root     root       774947 Aug 10 03:19 /usr/bin/perl
$

Hvis det viser seg at argumentet til delink er en link til en katalog, skal ikke den siste linjen vises, f. eks:

$ delink /var/mail
lrwxrwxrwx    1 root     daemon         10 Jan 22  2003 /var/mail -> spool/mail
I dette tilfellet er /var/spool/mail en katalog. Ingen output skal gis om man bruker delink direkte på en katalog, for eksempel /etc. Du kan anta at delink alltid mottar ett og bare ett argument.

c) Lag et bash-script med navn show som tar ett og bare ett argument og ellers avslutter med en feilmelding. Det skal bruke de to foregående scriptene where og delink på en slik måte at hvis et kjørbart program som ligger i $PATH gis som argument til show, vil det gi full path til programmet. Altså:

$ show emacs
lrwxrwxrwx    1 root     root           23 Jan 22  2003 /usr/bin/emacs -> /etc/alternatives/emacs
lrwxrwxrwx    1 root     root           16 May 30  2003 /etc/alternatives/emacs -> /usr/bin/emacs21
lrwxrwxrwx    1 root     root           10 Jan 22  2003 /usr/bin/emacs21 -> emacs-21.2
-rwxr-xr-x    1 root     root      3978292 Mar 22  2002 /usr/bin/emacs-21.2
og
$ show ls
-rwxr-xr-x    1 root     root        43784 Mar 18  2002 /bin/ls
Hvis argumentet ikke ligger i $PATH, skal en feilmelding gis. Du kan anta at where og delink ligger i $PATH.

Oppgave 3

I starten av denne oppgaven skal vi se på prosesser som multitaskes, men som må serialiseres når de bruker en felles variabel.

a) Hva er et kritisk avsnitt. Forklar kort.

b) Hva er en semafor. Forklar kort.

c) En semafor som er initialisert til S=1, brukes av 3 prosesser som jobber mot en felles variabel. Prosessene kaller alltid først wait, gjør et antall instruksjoner og kaller så signal. Forklar hvilke verdier S kan anta mens prosessene kjører.

d) Forklar kort hvordan Linux-kommandoen nice virker inn på det som skjer i Round Robin-køen.

e) Du og din nabo er koblet til samme HUB. Du kjører som root Ethereal på din maskin. Naboen din bruker ssh, ftp, telnet. For hvilke av de 3 appliaksjoene har du mulighet til å lese naboens passord? Forklar kort.

f) Du og din nabo er koblet til samme Switch. Du kjører som root Ethereal på din maskin. Naboen din bruker ssh, ftp og telnet. For hvilke av de 3 appliaksjoene har du mulighet til å lese naboens passord? Forklar kort.

g) Gitt følgende:

cube$ traceroute nexus
traceroute to nexus.iu.hio.no (128.39.89.10), 30 hops max, 38 byte packets
 1  cadeler30-gw.uninett.no (128.39.74.1)  0.769 ms  0.696 ms  0.579 ms
 2  nexus (128.39.89.10)  0.617 ms  0.443 ms  0.748 ms
Vil nexus motta cubes IP-adresse når cube sender pakker til nexus? Forklar kort.

h) Vil nexus motta cubes MAC-adresse når cube sender pakker til nexus? Forklar kort.

i) Hva er cadeler30-gw.uninett.no?

Oppgave 4

I denne oppgaven skal du skrive to Perl subrutiner som skal brukes i den siste oppgaven til å lage en enkel Honeypot; en port-lytter.

a) Lag en perl subrutine som tar en streng som argument. Denne strengen inneholder informasjon som skal legges til logg-filen honeypot.log. Anta at filen ligger i katalogen der programmet kjører. Hver nye informasjonsstreng i logg-filen skal starte med et tids/dato stempel; bruk en innebygd Perl-funksjon. Logg-filen skal åpnes og lukkes for hver gang info skrives til filen. Bruk lokale variabler.

b) Linux-kommandoen

lynx -source http://www.iana.org/assignments/port-numbers
gir blant annet informasjon om tcp-tjenester med linjer som
ftp              21/tcp    File Transfer [Control]
ssh              22/tcp    SSH Remote Login Protocol
telnet           23/tcp    Telnet
smtp             25/tcp    Simple Mail Transfer
Det er kun linjer på denne formen som inneholder strengen /tcp.

Skriv en Perl subrutine GetServiceNames som tar tar imot to parametre, min og max. Rutinen skal returnere et array indeksert med tcp-portnummere som ikke skal være mindre enn min og ikke større enn max. Verdien av arrayet med for eksempel index 22 skal være info om tcp-tjenesten med dette nummeret. I dette tilfellet strengen 'ssh (SSH Remote Login Protocol)' og tilsvarende for andre portnummere. Om det er portnummere mellom min og maks det ikke finnes info for, skal disse elementene ganske enkelt ikke defineres. Bruk lokale variabler.

Oppgave 5

En Honeypot er en host som lokker til seg hackere og prøver å logge nøyaktig hva de gjør. En slik host har i utgangspunktet ingen tjenester å tilby, så alle som prøver å komme inn bør betraktes som potensielle inntrengere. En port-lytter er den enkleste formen for Honeypot, et program som står og lytter på et antall porter og åpner en begrenset kommunikasjon hvis noen kobler seg til en port.

I denne oppgaven skal du skrive en slik port-lytter ved å bruke Perl-sockets. Programmet skal selv definere verdien på to variabler $min og $max som bestemmer hvilke porter som det skal lyttes på. Det vil si portene med nummer $min og $max og alle i mellom dem.

For hvert portnummer skal programmet gjøre en fork(), slik at det startes en egen prosess for hvert portnummer og dermed for hver socket-forbindelse. Hver child-prosess skal åpne en server-socket på sitt portnummer. Hvis det ikke går, skal en passende feilmelding skrives ut. Hvis socket'en kan opprettes og portnummeret for eksempel er 22, skal følgende informsajon skrives ut:

Lytter på TCP-port 22 ssh (SSH Remote Login Protocol)
Informasjonen om tjenestenavnene skal hentes med subrutinen GetServiceNames fra forrige oppgave. Hver child-prosess skal stå i en evig løkke og vente på oppkoblinger. Hvis det kommer en oppkobling, skal den trekke ut IP-adressen til inntrengeren og prøve å lese ett buffer med et recv()-kall. Deretter skal forbindelsen avsluttes og info, inkludert det leste bufferet, skrives til logg-filen ved hjelp av subrutinen writeLog fra forrige oppgave. Hvis det er en oppkobling på port 22 som sender 'heiiiii', skal følgende (eller tilsvarende) skrives til logg-filen:
Tue Dec  9 14:07:47 2003 Tilkobling på TCP-port 22 (ssh (SSH Remote Login Protocol)) fra 62.97.171.99.  heiiiii
Husk at writeLog selv legger på tidsstempelet. Du kan sette Reuse og Listen til 1 når du lager socket'ene og buffer-størrelsen til 1000.

Det er mulig for en prosess å lage mange samtidige sockets med forskjellige portnummere, ved å bruke en egen IO::Select modul. Ser du noen fordeler/ulemper ved å bruke en slik metode i forhold til å fork'e?

-SLUTT-



Hårek Haugerud 2003-12-12