summaryrefslogtreecommitdiffstats
path: root/doc/LaTeX/devel/0310-service-discovery.tex
blob: 307234fdf72f1c0ae0bb3aefb04f34cb5851aed2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Die Zuordnung von Clients zur Konsole erfolgt halb automatisch über ein
Service-Discovery-Modul. Jede Konsole sendet im Intervall von 7 Sekunden
einen Broadcast ins lokale Subnetz, um ihre Verfügbarkeit bekannt zu geben.
Die Clients können dadurch eine Liste von verfügbaren Servern anzeigen,
aus der der Benutzer nur noch den gewünschten auswählen muss.
Das Intervall sowie die verwendeten UDP-Ports für das Service-Discovery
können vor dem Kompilieren in der \textit{setup.h} festgelegt werden
\begin{verbatim}
#define SB_INTERVAL 7 // Broadcast interval in seconds
#define SD_PORT_CONSOLE 3491 // Not really used, Qt just wants a bind
#define SD_PORT_CLIENT 3492 // This is where we expect announcements
\end{verbatim}
Die zuständigen Klassen sind \textit{PVSServiceBroadcast} (Serverseitig) und
\textit{PVSServiceDiscovery} (Clientseitig).\\
Auf Seite des Clients erfolgt außerdem eine Kommunikation mit der GUI
über DBus, um verfügbare Sitzungen anzeigen zu lassen, und damit
die GUI den Daemon veranlassen kann, zu einer bestimmten Sitzung
zu verbinden.
Die Methode \textit{connectToSession} in \textit{PVSServiceDiscovery}
ist dafür zuständig, zu einem gegebenem Sitzungsnamen die nötigen
Daten zu ermitteln und eine Verbindung zu initialisieren.

\subsubsection{Absicherung und Verifikation der Identität}

Um das Fälschen bzw. Manipulieren von diesen Broadcasts zu verhindern,
sodass es nicht möglich ist, Man-in-the-Middle Angriffe oder ähnliches
durchzuführen, soll gewährleistet werden, dass eine angezeigte Sitzung
auch die ist, für die man sie hält.

Dafür wird auf das SSL-Protokoll zurückgegriffen. Zum einen bietet SSL
Verschlüsselung für Verbindungen an, und das Qt-Framework hat hierfür
auch schon einige Klassen parat. Zum anderen ist mit SSL durch seine
Zertifikate auch Identitätsverifikation möglich. Dazu kann das Zertifikat
des Servers anhand des Fingerprints auf Echtheit überprüft werden.
Beim Start der Konsole wird also, falls noch nicht vorhanden, ein neues
Serverzertifikat inklusive Schlüsselpaar erstellt, mit welchem Verbindungen
mit Clients fortan verschlüsselt werden. Außerdem wird der Fingerprint des
Zertifikats in den Service-Broadcasts übertragen, sodass die Clients
bereits vor der Verbindung den zu erwartenden Fingerprint kennen.
Somit kann beim Aufbau der Verbindung zur Konsole der Fingerprint
verglichen und eine eventuelle Manipulation erkannt werden.

Für die Eindeutigkeit ist nur noch eine feste Zuordnung von Sitzungsnamen,
welcher dem Benutzer angezeigt wird, zum Fingerprint der zugehörigen
Konsole notwendig. Dies wird mit Hilfe eines einfachen Algorithmus erreicht,
der aus dem Fingerprint einen lesbaren String erzeugt. Wichtig ist, dass
Konsole und Client hier denselben Algorithmus verwenden, damit der
Dozent an der Konsole den Studenten den korrekten Sitzungsnamen mitteilen
kann. Wird der Algorithmus auf Seite der Konsole verändert, müssen auch
alle Clients aktualisiert werden. Er befindet sich in der \textit{serviceDiscoveryUtil.h}
und heißt \textit{sha1ToReadable}.

Empfängt der Client einen Broadcast über einen neuen Server, baut dieser
zunächst zur Überprüfung eine Verbindung zu diesem Server auf und sofort wieder
ab, um den Fingerprint überprüfen zu können. Nur wenn dieser mit dem
angekündigten Fingerprint aus dem Broadcast übereinstimmt, wird die Sitzung
dem Benutzer zur Auswahl angezeigt.

Die Überprüfung geschieht nicht sofort beim Empfang eines Service-Announcements
sondern verzögert in einem Timer, und dabei auch jeweils nur ein Server
in jedem Timer-Aufruf. Dies soll Missbrauch durch gefälschte Broadcastpakete
verhindern oder zumindest stark verlangsamen. Entsprechende Mechanismen gegen
Missbrauch finden sich in \textit{PVSServiceDiscovery::handleDiscovery} sowie
\textit{PVSServiceDiscovery::timerEvent}.

\subsubsection{Generierung von Sitzungsnamen}

Hier ist prinzipiell viel Spielraum für Kreativität vorhanden, beachtet werden
sollte lediglich, dass die Zahl der möglichen Namen, die durch den Algorithmus
erzeugt werden können, hoch genug ist, um nicht in kurzer Zeit durch einen
Brute-Force-Angriff einen Fingerprint mit dem selben Sitzungsnamen erzeugen zu
können. Außerdem sollte die Verteilung der zufälligen Namen über den Raum der
möglichen Namen etwa gleichmäßig sein.

Der momentan verwendete Algorithmus generiert fünfsilbige Wörter, wobei jede
Silbe aus einem Konsonanten und einem Vokal besteht. Die Konsonanten werden
aus einer Liste von 13 Stück ausgewählt, wobei identisch oder zu ähnlich klingende
Konsonanten herausgefiltert wurden, um bei der mündlichen Übertragung keine
Ambiguitäten zu erzeugen. mit einer Wahrscheinlichkeit von 25\% wird einer Silbe
ein \textbf{n} angehängt. Damit sind $130^5 = 37.129.300.000$ (37 Mrd.)
unterschiedliche Sitzungsnamen möglich, was zwar deutlich weniger sind, als bei
einem 160Bit langen SHA1-Hash, allerdings ist dies bezogen auf das Einsatzgebiet
mehr als ausreichend. Alternativ bleibt natürlich nach wie vor das verwenden
alternativer Algorithmen die einen größeren Raum an möglichen Namen haben.