15. STUN Attributes (STUN-Attribute)
Nach dem STUN-Header folgen null oder mehr Attribute. Jedes Attribut MUSS TLV-kodiert sein, mit einem 16-Bit-Typ, einer 16-Bit-Länge und einem Wert. Jedes STUN-Attribut MUSS an einer 32-Bit-Grenze enden. Wie oben erwähnt, werden alle Felder in einem Attribut mit dem höchstwertigen Bit zuerst übertragen.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Value (variable) ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Abbildung 4: Format der STUN-Attribute
Der Wert im Längenfeld MUSS die Länge des Value-Teils des Attributs vor dem Padding enthalten, gemessen in Bytes. Da STUN Attribute an 32-Bit-Grenzen ausrichtet, werden Attribute, deren Inhalt kein Vielfaches von 4 Bytes ist, mit 1, 2 oder 3 Bytes Padding aufgefüllt, sodass ihr Wert ein Vielfaches von 4 Bytes enthält. Die Padding-Bits werden ignoriert und können beliebige Werte haben.
Jeder Attributtyp KANN mehr als einmal in einer STUN-Nachricht erscheinen. Sofern nicht anders angegeben, ist die Reihenfolge des Auftretens signifikant: Nur das erste Vorkommen muss von einem Empfänger verarbeitet werden, und alle Duplikate KÖNNEN von einem Empfänger ignoriert werden.
Um zukünftigen Revisionen dieser Spezifikation zu ermöglichen, bei Bedarf neue Attribute hinzuzufügen, ist der Attributraum in zwei Bereiche unterteilt. Attributtypen mit Werten zwischen 0x0000 und 0x7FFF sind verständnispflichtige Attribute, was bedeutet, dass der STUN-Agent die Nachricht nicht erfolgreich verarbeiten kann, es sei denn, er versteht das Attribut. Attributtypen mit Werten zwischen 0x8000 und 0xFFFF sind verständnisoptionale Attribute, was bedeutet, dass diese Attribute vom STUN-Agent ignoriert werden können, wenn er sie nicht versteht.
Der Satz von STUN-Attributtypen wird von der IANA verwaltet. Der von dieser Spezifikation definierte anfängliche Satz befindet sich in Abschnitt 18.2.
Der Rest dieses Abschnitts beschreibt das Format der verschiedenen in dieser Spezifikation definierten Attribute.
15.1. MAPPED-ADDRESS
Das MAPPED-ADDRESS-Attribut gibt eine reflexive Transportadresse des Clients an. Es besteht aus einer 8-Bit-Adressfamilie und einem 16-Bit-Port, gefolgt von einem Wert fester Länge, der die IP-Adresse darstellt. Wenn die Adressfamilie IPv4 ist, MUSS die Adresse 32 Bit betragen. Wenn die Adressfamilie IPv6 ist, MUSS die Adresse 128 Bit betragen. Alle Felder müssen in Netzwerk-Byte-Reihenfolge sein.
Das Format des MAPPED-ADDRESS-Attributs ist:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 0 0 0 0 0| Family | Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Address (32 bits or 128 bits) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Abbildung 5: Format des MAPPED-ADDRESS-Attributs
Die Adressfamilie kann die folgenden Werte annehmen:
- 0x01: IPv4
- 0x02: IPv6
Die ersten 8 Bits des MAPPED-ADDRESS MÜSSEN auf 0 gesetzt werden und MÜSSEN von Empfängern ignoriert werden. Diese Bits sind vorhanden, um Parameter an natürlichen 32-Bit-Grenzen auszurichten.
Dieses Attribut wird nur von Servern verwendet, um Rückwärtskompatibilität mit RFC 3489 [RFC3489]-Clients zu erreichen.
15.2. XOR-MAPPED-ADDRESS
Das XOR-MAPPED-ADDRESS-Attribut ist identisch mit dem MAPPED-ADDRESS-Attribut, außer dass die reflexive Transportadresse durch die XOR-Funktion verschleiert wird.
Das Format des XOR-MAPPED-ADDRESS ist:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|x x x x x x x x| Family | X-Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| X-Address (Variable)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Abbildung 6: Format des XOR-MAPPED-ADDRESS-Attributs
Family repräsentiert die IP-Adressfamilie und wird identisch zur Family in MAPPED-ADDRESS kodiert.
X-Port wird berechnet, indem der gemappte Port in Host-Byte-Reihenfolge genommen, mit den höchstwertigen 16 Bits des Magic Cookie XOR-verknüpft und das Ergebnis in Netzwerk-Byte-Reihenfolge konvertiert wird. Wenn die IP-Adressfamilie IPv4 ist, wird X-Address berechnet, indem die gemappte IP-Adresse in Host-Byte-Reihenfolge genommen, mit dem Magic Cookie XOR-verknüpft und das Ergebnis in Netzwerk-Byte-Reihenfolge konvertiert wird. Wenn die IP-Adressfamilie IPv6 ist, wird X-Address berechnet, indem die gemappte IP-Adresse in Host-Byte-Reihenfolge genommen, mit der Verkettung des Magic Cookie und der 96-Bit-Transaktions-ID XOR-verknüpft und das Ergebnis in Netzwerk-Byte-Reihenfolge konvertiert wird.
Die Regeln für die Kodierung und Verarbeitung der ersten 8 Bits des Attributwerts, die Regeln für die Behandlung mehrerer Vorkommen des Attributs und die Regeln für die Verarbeitung von Adressfamilien sind dieselben wie für MAPPED-ADDRESS.
Hinweis: XOR-MAPPED-ADDRESS und MAPPED-ADDRESS unterscheiden sich nur in ihrer Kodierung der Transportadresse. Ersteres kodiert die Transportadresse durch exklusives Oder mit dem Magic Cookie. Letzteres kodiert es direkt binär. RFC 3489 spezifizierte ursprünglich nur MAPPED-ADDRESS. Die Bereitstellungserfahrung zeigte jedoch, dass einige NATs die 32-Bit-Binär-Payloads neu schreiben, die die öffentliche IP-Adresse des NAT enthalten, wie z.B. das MAPPED-ADDRESS-Attribut von STUN, in einem wohlmeinenden, aber fehlgeleiteten Versuch, eine generische ALG-Funktion bereitzustellen. Ein solches Verhalten beeinträchtigt den Betrieb von STUN und führt auch zum Fehlschlagen der Nachrichtenintegritätsprüfung von STUN.
15.3. USERNAME
Das USERNAME-Attribut wird für die Nachrichtenintegrität verwendet. Es identifiziert die Benutzernamen- und Passwortkombination, die bei der Nachrichtenintegritätsprüfung verwendet wird.
Der Wert von USERNAME ist ein Wert variabler Länge. Er MUSS eine UTF-8 [RFC3629]-kodierte Sequenz von weniger als 513 Bytes enthalten und MUSS mit SASLprep [RFC4013] verarbeitet worden sein.
15.4. MESSAGE-INTEGRITY
Das MESSAGE-INTEGRITY-Attribut enthält einen HMAC-SHA1 [RFC2104] der STUN-Nachricht. Das MESSAGE-INTEGRITY-Attribut kann in jedem STUN-Nachrichtentyp vorhanden sein. Da es den SHA1-Hash verwendet, wird der HMAC 20 Bytes betragen. Der als Eingabe für HMAC verwendete Text ist die STUN-Nachricht, einschließlich des Headers, bis einschließlich des Attributs, das dem MESSAGE-INTEGRITY-Attribut vorausgeht. Mit Ausnahme des FINGERPRINT-Attributs (das nach MESSAGE-INTEGRITY erscheint) MÜSSEN Agents alle anderen Attribute ignorieren, die MESSAGE-INTEGRITY folgen.
Der Schlüssel für den HMAC hängt davon ab, ob Langzeit- oder Kurzzeit-Credentials verwendet werden. Für Langzeit-Credentials beträgt der Schlüssel 16 Bytes:
key = MD5(username ":" realm ":" SASLprep(password))
Das heißt, der 16-Byte-Schlüssel wird gebildet, indem der MD5-Hash des Ergebnisses der Verkettung der folgenden fünf Felder genommen wird: (1) Der Benutzername, mit entfernten Anführungszeichen und abschließenden Nullen, aus dem USERNAME-Attribut (falls vorhanden); (2) Ein einzelner Doppelpunkt; (3) Der Realm, mit entfernten Anführungszeichen und abschließenden Nullen; (4) Ein einzelner Doppelpunkt; und (5) Das Passwort, mit entfernten abschließenden Nullen und nach Verarbeitung mit SASLprep. Wenn beispielsweise der Benutzername 'user', der Realm 'realm' und das Passwort 'pass' war, wäre der 16-Byte-HMAC-Schlüssel das Ergebnis der Ausführung eines MD5-Hash auf die Zeichenkette 'user:realm:pass', wobei der Hash 0x8493fbc53ba582fb4c044c456bdc40eb wäre.
Für Kurzzeit-Credentials:
key = SASLprep(password)
wobei MD5 in RFC 1321 [RFC1321] definiert ist und SASLprep() in RFC 4013 [RFC4013] definiert ist.
Die Struktur des Schlüssels bei Verwendung mit Langzeit-Credentials erleichtert die Bereitstellung in Systemen, die auch SIP verwenden. Typischerweise speichern SIP-Systeme, die den Digest-Authentifizierungsmechanismus von SIP verwenden, das Passwort nicht tatsächlich in der Datenbank. Stattdessen speichern sie einen Wert namens H(A1), der dem oben definierten Schlüssel entspricht.
Basierend auf den obigen Regeln umfasst der zum Konstruieren von MESSAGE-INTEGRITY verwendete Hash das Längenfeld aus dem STUN-Nachrichtenheader. Vor der Durchführung des Hash MUSS das MESSAGE-INTEGRITY-Attribut in die Nachricht eingefügt werden (mit Dummy-Inhalt). Die Länge MUSS dann so gesetzt werden, dass sie auf die Länge der Nachricht bis einschließlich des MESSAGE-INTEGRITY-Attributs selbst zeigt, jedoch alle Attribute danach ausschließt. Sobald die Berechnung durchgeführt wurde, kann der Wert des MESSAGE-INTEGRITY-Attributs ausgefüllt werden, und der Wert der Länge im STUN-Header kann auf seinen korrekten Wert gesetzt werden -- die Länge der gesamten Nachricht. In ähnlicher Weise sollte beim Validieren des MESSAGE-INTEGRITY das Längenfeld angepasst werden, um auf das Ende des MESSAGE-INTEGRITY-Attributs zu zeigen, bevor der HMAC berechnet wird. Eine solche Anpassung ist erforderlich, wenn Attribute wie FINGERPRINT nach MESSAGE-INTEGRITY erscheinen.
15.5. FINGERPRINT
Das FINGERPRINT-Attribut KANN in allen STUN-Nachrichten vorhanden sein. Der Wert des Attributs wird als CRC-32 der STUN-Nachricht bis zum (aber ausschließlich) FINGERPRINT-Attribut selbst berechnet, XOR-verknüpft mit dem 32-Bit-Wert 0x5354554e (das XOR hilft in Fällen, in denen ein Anwendungspaket auch CRC-32 darin verwendet). Das 32-Bit-CRC ist das in ITU V.42 [ITU.V42.2002] definierte, das ein Generatorpolynom von x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 hat. Wenn vorhanden, MUSS das FINGERPRINT-Attribut das letzte Attribut in der Nachricht sein und wird daher nach MESSAGE-INTEGRITY erscheinen.
Das FINGERPRINT-Attribut kann helfen, STUN-Pakete von Paketen anderer Protokolle zu unterscheiden. Siehe Abschnitt 8.
Wie bei MESSAGE-INTEGRITY deckt das im FINGERPRINT-Attribut verwendete CRC das Längenfeld aus dem STUN-Nachrichtenheader ab. Daher muss dieser Wert korrekt sein und das CRC-Attribut als Teil der Nachrichtenlänge enthalten, bevor das CRC berechnet wird. Bei Verwendung des FINGERPRINT-Attributs in einer Nachricht wird das Attribut zunächst mit einem Dummy-Wert in die Nachricht eingefügt, dann wird das CRC berechnet und dann wird der Wert des Attributs aktualisiert. Wenn auch das MESSAGE-INTEGRITY-Attribut vorhanden ist, muss es den korrekten Nachrichtenintegritätswert haben, bevor das CRC berechnet wird, da das CRC auch über den Wert des MESSAGE-INTEGRITY-Attributs erfolgt.
15.6. ERROR-CODE
Das ERROR-CODE-Attribut wird in Fehlerantwortnachrichten verwendet. Es enthält einen numerischen Fehlercodewert im Bereich von 300 bis 699 plus einen textuellen Begründungssatz, der in UTF-8 [RFC3629] kodiert ist, und ist in seinen Codezuweisungen und seiner Semantik mit SIP [RFC3261] und HTTP [RFC2616] konsistent. Der Begründungssatz ist für die Benutzernutzung gedacht und kann alles sein, was für den Fehlercode geeignet ist. Empfohlene Begründungssätze für die definierten Fehlercodes sind im IANA-Register für Fehlercodes enthalten. Der Begründungssatz MUSS eine UTF-8 [RFC3629]-kodierte Sequenz von weniger als 128 Zeichen sein (die bis zu 763 Bytes lang sein kann).
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved, should be 0 |Class| Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reason Phrase (variable) ..
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Abbildung 7: ERROR-CODE-Attribut
Um die Verarbeitung zu erleichtern, wird die Klasse des Fehlercodes (die Hunderterziffer) separat vom Rest des Codes kodiert, wie in Abbildung 7 gezeigt.
Die reservierten Bits SOLLTEN 0 sein und dienen der Ausrichtung an 32-Bit-Grenzen. Empfänger MÜSSEN diese Bits ignorieren. Die Klasse repräsentiert die Hunderterziffer des Fehlercodes. Der Wert MUSS zwischen 3 und 6 liegen. Die Nummer repräsentiert den Fehlercode Modulo 100, und ihr Wert MUSS zwischen 0 und 99 liegen.
Die folgenden Fehlercodes sind zusammen mit ihren empfohlenen Begründungssätzen definiert:
300 Try Alternate: Der Client sollte einen alternativen Server für diese Anfrage kontaktieren. Diese Fehlerantwort DARF nur gesendet werden, wenn die Anfrage ein USERNAME-Attribut und ein gültiges MESSAGE-INTEGRITY-Attribut enthielt; andernfalls DARF sie NICHT gesendet werden, und Fehlercode 400 (Bad Request) wird vorgeschlagen. Diese Fehlerantwort MUSS mit dem MESSAGE-INTEGRITY-Attribut geschützt werden, und Empfänger MÜSSEN das MESSAGE-INTEGRITY dieser Antwort validieren, bevor sie sich zu einem alternativen Server umleiten.
Hinweis: Das Versäumnis, die Nachrichtenintegrität für eine 300-Antwort zu generieren und zu validieren, ermöglicht es einem Angreifer im Pfad, eine 300-Antwort zu fälschen, wodurch nachfolgende STUN-Nachrichten an ein Opfer gesendet werden.
400 Bad Request: Die Anfrage war fehlerhaft. Der Client SOLLTE die Anfrage NICHT ohne Änderung gegenüber dem vorherigen Versuch wiederholen. Der Server ist möglicherweise nicht in der Lage, ein gültiges MESSAGE-INTEGRITY für diesen Fehler zu generieren, daher DARF der Client KEIN gültiges MESSAGE-INTEGRITY-Attribut bei dieser Antwort erwarten.
401 Unauthorized: Die Anfrage enthielt nicht die korrekten Anmeldeinformationen, um fortzufahren. Der Client sollte die Anfrage mit geeigneten Anmeldeinformationen wiederholen.
420 Unknown Attribute: Der Server erhielt ein STUN-Paket, das ein verständnispflichtiges Attribut enthielt, das er nicht verstand. Der Server MUSS dieses unbekannte Attribut in das UNKNOWN-ATTRIBUTE-Attribut seiner Fehlerantwort einfügen.
438 Stale Nonce: Die vom Client verwendete NONCE war nicht mehr gültig. Der Client sollte es erneut versuchen und dabei die in der Antwort bereitgestellte NONCE verwenden.
500 Server Error: Der Server hat einen vorübergehenden Fehler erlitten. Der Client sollte es erneut versuchen.
15.7. REALM
Das REALM-Attribut kann in Anfragen und Antworten vorhanden sein. Es enthält Text, der der Grammatik für "realm-value" entspricht, wie in RFC 3261 [RFC3261] beschrieben, jedoch ohne die doppelten Anführungszeichen und ihre umgebenden Leerzeichen. Das heißt, es ist ein nicht zitierter realm-value (und ist daher eine Sequenz von qdtext oder quoted-pair). Es MUSS eine UTF-8 [RFC3629]-kodierte Sequenz von weniger als 128 Zeichen sein (die bis zu 763 Bytes lang sein kann) und MUSS mit SASLprep [RFC4013] verarbeitet worden sein.
Das Vorhandensein des REALM-Attributs in einer Anfrage zeigt an, dass Langzeit-Credentials für die Authentifizierung verwendet werden. Das Vorhandensein in bestimmten Fehlerantworten zeigt an, dass der Server möchte, dass der Client Langzeit-Credentials für die Authentifizierung verwendet.
15.8. NONCE
Das NONCE-Attribut kann in Anfragen und Antworten vorhanden sein. Es enthält eine Sequenz von qdtext oder quoted-pair, die in RFC 3261 [RFC3261] definiert sind. Beachten Sie, dass dies bedeutet, dass das NONCE-Attribut keine tatsächlichen Anführungszeichen enthalten wird. Siehe RFC 2617 [RFC2617], Abschnitt 4.3, für Anleitungen zur Auswahl von Nonce-Werten in einem Server.
Es MUSS weniger als 128 Zeichen sein (die bis zu 763 Bytes lang sein können).
15.9. UNKNOWN-ATTRIBUTES
Das UNKNOWN-ATTRIBUTES-Attribut ist nur in einer Fehlerantwort vorhanden, wenn der Antwortcode im ERROR-CODE-Attribut 420 ist.
Das Attribut enthält eine Liste von 16-Bit-Werten, von denen jeder einen Attributtyp darstellt, der vom Server nicht verstanden wurde.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute 1 Type | Attribute 2 Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute 3 Type | Attribute 4 Type ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Abbildung 8: Format des UNKNOWN-ATTRIBUTES-Attributs
Hinweis: In [RFC3489] wurde dieses Feld durch Duplizieren des letzten Attributs auf 32 aufgefüllt. In dieser Version der Spezifikation werden stattdessen die normalen Padding-Regeln für Attribute verwendet.
15.10. SOFTWARE
Das SOFTWARE-Attribut enthält eine textuelle Beschreibung der vom sendenden Agent verwendeten Software. Es wird von Clients und Servern verwendet. Sein Wert SOLLTE Hersteller und Versionsnummer enthalten. Das Attribut hat keinen Einfluss auf den Betrieb des Protokolls und dient nur als Werkzeug für Diagnose- und Debugging-Zwecke. Der Wert von SOFTWARE ist variabler Länge. Es MUSS eine UTF-8 [RFC3629]-kodierte Sequenz von weniger als 128 Zeichen sein (die bis zu 763 Bytes lang sein kann).
15.11. ALTERNATE-SERVER
Der alternative Server repräsentiert eine alternative Transportadresse, die einen anderen STUN-Server identifiziert, den der STUN-Client versuchen sollte.
Er wird auf die gleiche Weise wie MAPPED-ADDRESS kodiert und bezieht sich daher auf einen einzelnen Server über eine IP-Adresse. Die IP-Adressfamilie MUSS identisch mit der der Quell-IP-Adresse der Anfrage sein.