Passa al contenuto principale

15. STUN Attributes (Attributi STUN)

Dopo l'intestazione STUN ci sono zero o più attributi. Ogni attributo DEVE essere codificato in TLV, con un tipo a 16 bit, una lunghezza a 16 bit e un valore. Ogni attributo STUN DEVE terminare su un confine a 32 bit. Come menzionato sopra, tutti i campi in un attributo sono trasmessi con il bit più significativo per primo.

    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) ....
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figura 4: Formato degli attributi STUN

Il valore nel campo lunghezza DEVE contenere la lunghezza della parte Value dell'attributo, prima del padding, misurata in byte. Poiché STUN allinea gli attributi su confini a 32 bit, gli attributi il cui contenuto non è un multiplo di 4 byte sono riempiti con 1, 2 o 3 byte di padding in modo che il loro valore contenga un multiplo di 4 byte. I bit di padding sono ignorati e possono avere qualsiasi valore.

Qualsiasi tipo di attributo PUÒ apparire più di una volta in un messaggio STUN. A meno che non sia specificato diversamente, l'ordine di apparizione è significativo: solo la prima occorrenza deve essere elaborata da un ricevitore, e qualsiasi duplicato PUÒ essere ignorato da un ricevitore.

Per consentire alle future revisioni di questa specifica di aggiungere nuovi attributi se necessario, lo spazio degli attributi è diviso in due intervalli. I tipi di attributo con valori tra 0x0000 e 0x7FFF sono attributi a comprensione obbligatoria, il che significa che l'agente STUN non può elaborare con successo il messaggio a meno che non comprenda l'attributo. I tipi di attributo con valori tra 0x8000 e 0xFFFF sono attributi a comprensione opzionale, il che significa che questi attributi possono essere ignorati dall'agente STUN se non li comprende.

L'insieme dei tipi di attributo STUN è mantenuto da IANA. L'insieme iniziale definito da questa specifica si trova nella Sezione 18.2.

Il resto di questa sezione descrive il formato dei vari attributi definiti in questa specifica.

15.1. MAPPED-ADDRESS

L'attributo MAPPED-ADDRESS indica un indirizzo di trasporto riflessivo del client. È composto da una famiglia di indirizzi a 8 bit e da una porta a 16 bit, seguiti da un valore di lunghezza fissa che rappresenta l'indirizzo IP. Se la famiglia di indirizzi è IPv4, l'indirizzo DEVE essere di 32 bit. Se la famiglia di indirizzi è IPv6, l'indirizzo DEVE essere di 128 bit. Tutti i campi devono essere nell'ordine dei byte di rete.

Il formato dell'attributo MAPPED-ADDRESS è:

    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) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figura 5: Formato dell'attributo MAPPED-ADDRESS

La famiglia di indirizzi può assumere i seguenti valori:

  • 0x01: IPv4
  • 0x02: IPv6

I primi 8 bit del MAPPED-ADDRESS DEVONO essere impostati su 0 e DEVONO essere ignorati dai ricevitori. Questi bit sono presenti per allineare i parametri su confini naturali a 32 bit.

Questo attributo è utilizzato solo dai server per ottenere la retrocompatibilità con i client RFC 3489 [RFC3489].

15.2. XOR-MAPPED-ADDRESS

L'attributo XOR-MAPPED-ADDRESS è identico all'attributo MAPPED-ADDRESS, tranne per il fatto che l'indirizzo di trasporto riflessivo è offuscato attraverso la funzione XOR.

Il formato del XOR-MAPPED-ADDRESS è:

   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)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figura 6: Formato dell'attributo XOR-MAPPED-ADDRESS

Family rappresenta la famiglia di indirizzi IP ed è codificata in modo identico a Family in MAPPED-ADDRESS.

X-Port è calcolato prendendo la porta mappata nell'ordine dei byte dell'host, eseguendo XOR con i 16 bit più significativi del magic cookie, e quindi convertendo il risultato nell'ordine dei byte di rete. Se la famiglia di indirizzi IP è IPv4, X-Address è calcolato prendendo l'indirizzo IP mappato nell'ordine dei byte dell'host, eseguendo XOR con il magic cookie, e convertendo il risultato nell'ordine dei byte di rete. Se la famiglia di indirizzi IP è IPv6, X-Address è calcolato prendendo l'indirizzo IP mappato nell'ordine dei byte dell'host, eseguendo XOR con la concatenazione del magic cookie e dell'ID di transazione a 96 bit, e convertendo il risultato nell'ordine dei byte di rete.

Le regole per la codifica e l'elaborazione dei primi 8 bit del valore dell'attributo, le regole per la gestione delle occorrenze multiple dell'attributo e le regole per l'elaborazione delle famiglie di indirizzi sono le stesse di MAPPED-ADDRESS.

Nota: XOR-MAPPED-ADDRESS e MAPPED-ADDRESS differiscono solo nella loro codifica dell'indirizzo di trasporto. Il primo codifica l'indirizzo di trasporto tramite OR esclusivo con il magic cookie. Il secondo lo codifica direttamente in forma binaria. RFC 3489 specificava originariamente solo MAPPED-ADDRESS. Tuttavia, l'esperienza di deployment ha rivelato che alcuni NAT riscrivono i payload binari a 32 bit contenenti l'indirizzo IP pubblico del NAT, come l'attributo MAPPED-ADDRESS di STUN, in un tentativo ben intenzionato ma mal guidato di fornire una funzione ALG generica. Tale comportamento interferisce con il funzionamento di STUN e causa anche il fallimento del controllo di integrità dei messaggi di STUN.

15.3. USERNAME

L'attributo USERNAME è utilizzato per l'integrità dei messaggi. Identifica la combinazione nome utente e password utilizzata nel controllo di integrità dei messaggi.

Il valore di USERNAME è un valore di lunghezza variabile. DEVE contenere una sequenza codificata UTF-8 [RFC3629] di meno di 513 byte e DEVE essere stata elaborata utilizzando SASLprep [RFC4013].

15.4. MESSAGE-INTEGRITY

L'attributo MESSAGE-INTEGRITY contiene un HMAC-SHA1 [RFC2104] del messaggio STUN. L'attributo MESSAGE-INTEGRITY può essere presente in qualsiasi tipo di messaggio STUN. Poiché utilizza l'hash SHA1, l'HMAC sarà di 20 byte. Il testo utilizzato come input per HMAC è il messaggio STUN, inclusa l'intestazione, fino a e incluso l'attributo che precede l'attributo MESSAGE-INTEGRITY. Ad eccezione dell'attributo FINGERPRINT (che appare dopo MESSAGE-INTEGRITY), gli agenti DEVONO ignorare tutti gli altri attributi che seguono MESSAGE-INTEGRITY.

La chiave per l'HMAC dipende dall'utilizzo di credenziali a lungo termine o a breve termine. Per le credenziali a lungo termine, la chiave è di 16 byte:

key = MD5(username ":" realm ":" SASLprep(password))

Cioè, la chiave a 16 byte è formata prendendo l'hash MD5 del risultato della concatenazione dei seguenti cinque campi: (1) Il nome utente, con virgolette e null finali rimossi, dall'attributo USERNAME (se presente); (2) Un singolo due punti; (3) Il realm, con virgolette e null finali rimossi; (4) Un singolo due punti; e (5) La password, con null finali rimossi e dopo l'elaborazione utilizzando SASLprep. Ad esempio, se il nome utente era 'user', il realm era 'realm' e la password era 'pass', allora la chiave HMAC a 16 byte sarebbe il risultato dell'esecuzione di un hash MD5 sulla stringa 'user:realm:pass', con l'hash pari a 0x8493fbc53ba582fb4c044c456bdc40eb.

Per le credenziali a breve termine:

key = SASLprep(password)

dove MD5 è definito in RFC 1321 [RFC1321] e SASLprep() è definito in RFC 4013 [RFC4013].

La struttura della chiave quando utilizzata con credenziali a lungo termine facilita il deployment in sistemi che utilizzano anche SIP. Tipicamente, i sistemi SIP che utilizzano il meccanismo di autenticazione digest di SIP non memorizzano effettivamente la password nel database. Piuttosto, memorizzano un valore chiamato H(A1), che è uguale alla chiave definita sopra.

In base alle regole sopra, l'hash utilizzato per costruire MESSAGE-INTEGRITY include il campo lunghezza dall'intestazione del messaggio STUN. Prima di eseguire l'hash, l'attributo MESSAGE-INTEGRITY DEVE essere inserito nel messaggio (con contenuto fittizio). La lunghezza DEVE quindi essere impostata per puntare alla lunghezza del messaggio fino a e incluso l'attributo MESSAGE-INTEGRITY stesso, ma escludendo tutti gli attributi dopo di esso. Una volta eseguita la computazione, il valore dell'attributo MESSAGE-INTEGRITY può essere riempito e il valore della lunghezza nell'intestazione STUN può essere impostato sul suo valore corretto -- la lunghezza dell'intero messaggio. Similmente, quando si convalida MESSAGE-INTEGRITY, il campo lunghezza dovrebbe essere regolato per puntare alla fine dell'attributo MESSAGE-INTEGRITY prima di calcolare l'HMAC. Tale regolazione è necessaria quando attributi, come FINGERPRINT, appaiono dopo MESSAGE-INTEGRITY.

15.5. FINGERPRINT

L'attributo FINGERPRINT PUÒ essere presente in tutti i messaggi STUN. Il valore dell'attributo è calcolato come il CRC-32 del messaggio STUN fino a (ma escludendo) l'attributo FINGERPRINT stesso, in XOR con il valore a 32 bit 0x5354554e (l'XOR aiuta nei casi in cui un pacchetto applicativo utilizza anche CRC-32 al suo interno). Il CRC a 32 bit è quello definito in ITU V.42 [ITU.V42.2002], che ha un polinomio generatore di x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1. Quando presente, l'attributo FINGERPRINT DEVE essere l'ultimo attributo nel messaggio, e quindi apparirà dopo MESSAGE-INTEGRITY.

L'attributo FINGERPRINT può aiutare a distinguere i pacchetti STUN dai pacchetti di altri protocolli. Vedere Sezione 8.

Come con MESSAGE-INTEGRITY, il CRC utilizzato nell'attributo FINGERPRINT copre il campo lunghezza dall'intestazione del messaggio STUN. Pertanto, questo valore deve essere corretto e includere l'attributo CRC come parte della lunghezza del messaggio, prima del calcolo del CRC. Quando si utilizza l'attributo FINGERPRINT in un messaggio, l'attributo viene prima posizionato nel messaggio con un valore fittizio, quindi viene calcolato il CRC, e quindi viene aggiornato il valore dell'attributo. Se è presente anche l'attributo MESSAGE-INTEGRITY, deve avere il valore di integrità del messaggio corretto prima che venga calcolato il CRC, poiché il CRC viene eseguito anche sul valore dell'attributo MESSAGE-INTEGRITY.

15.6. ERROR-CODE

L'attributo ERROR-CODE è utilizzato nei messaggi di risposta di errore. Contiene un valore di codice di errore numerico nell'intervallo da 300 a 699 più una frase di ragione testuale codificata in UTF-8 [RFC3629], ed è coerente nelle sue assegnazioni di codice e nella semantica con SIP [RFC3261] e HTTP [RFC2616]. La frase di ragione è destinata al consumo dell'utente e può essere qualsiasi cosa appropriata per il codice di errore. Le frasi di ragione raccomandate per i codici di errore definiti sono incluse nel registro IANA per i codici di errore. La frase di ragione DEVE essere una sequenza codificata UTF-8 [RFC3629] di meno di 128 caratteri (che può essere lunga fino a 763 byte).

    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) ..
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figura 7: Attributo ERROR-CODE

Per facilitare l'elaborazione, la classe del codice di errore (la cifra delle centinaia) è codificata separatamente dal resto del codice, come mostrato nella Figura 7.

I bit riservati DOVREBBERO essere 0 e sono per l'allineamento su confini a 32 bit. I ricevitori DEVONO ignorare questi bit. La classe rappresenta la cifra delle centinaia del codice di errore. Il valore DEVE essere tra 3 e 6. Il numero rappresenta il codice di errore modulo 100, e il suo valore DEVE essere tra 0 e 99.

I seguenti codici di errore, insieme alle loro frasi di ragione raccomandate, sono definiti:

300 Try Alternate: Il client dovrebbe contattare un server alternativo per questa richiesta. Questa risposta di errore DEVE essere inviata solo se la richiesta includeva un attributo USERNAME e un attributo MESSAGE-INTEGRITY valido; altrimenti, NON DEVE essere inviata e si suggerisce il codice di errore 400 (Bad Request). Questa risposta di errore DEVE essere protetta con l'attributo MESSAGE-INTEGRITY, e i ricevitori DEVONO convalidare il MESSAGE-INTEGRITY di questa risposta prima di reindirizzarsi a un server alternativo.

Nota: Il mancato generare e convalidare l'integrità dei messaggi per una risposta 300 consente a un attaccante sul percorso di falsificare una risposta 300, causando così l'invio di successivi messaggi STUN a una vittima.

400 Bad Request: La richiesta era malformata. Il client NON DOVREBBE ritentare la richiesta senza modifiche rispetto al tentativo precedente. Il server potrebbe non essere in grado di generare un MESSAGE-INTEGRITY valido per questo errore, quindi il client NON DEVE aspettarsi un attributo MESSAGE-INTEGRITY valido su questa risposta.

401 Unauthorized: La richiesta non conteneva le credenziali corrette per procedere. Il client dovrebbe ritentare la richiesta con le credenziali appropriate.

420 Unknown Attribute: Il server ha ricevuto un pacchetto STUN contenente un attributo a comprensione obbligatoria che non ha compreso. Il server DEVE inserire questo attributo sconosciuto nell'attributo UNKNOWN-ATTRIBUTE della sua risposta di errore.

438 Stale Nonce: Il NONCE utilizzato dal client non era più valido. Il client dovrebbe ritentare, utilizzando il NONCE fornito nella risposta.

500 Server Error: Il server ha subito un errore temporaneo. Il client dovrebbe ritentare.

15.7. REALM

L'attributo REALM può essere presente nelle richieste e nelle risposte. Contiene testo che soddisfa la grammatica per "realm-value" come descritto in RFC 3261 [RFC3261] ma senza le virgolette doppie e il loro spazio bianco circostante. Cioè, è un realm-value non quotato (e quindi è una sequenza di qdtext o quoted-pair). DEVE essere una sequenza codificata UTF-8 [RFC3629] di meno di 128 caratteri (che può essere lunga fino a 763 byte), e DEVE essere stata elaborata utilizzando SASLprep [RFC4013].

La presenza dell'attributo REALM in una richiesta indica che vengono utilizzate credenziali a lungo termine per l'autenticazione. La presenza in certe risposte di errore indica che il server desidera che il client utilizzi una credenziale a lungo termine per l'autenticazione.

15.8. NONCE

L'attributo NONCE può essere presente nelle richieste e nelle risposte. Contiene una sequenza di qdtext o quoted-pair, che sono definiti in RFC 3261 [RFC3261]. Si noti che questo significa che l'attributo NONCE non conterrà caratteri di virgoletta effettivi. Vedere RFC 2617 [RFC2617], Sezione 4.3, per indicazioni sulla selezione dei valori nonce in un server.

DEVE essere inferiore a 128 caratteri (che può essere lungo fino a 763 byte).

15.9. UNKNOWN-ATTRIBUTES

L'attributo UNKNOWN-ATTRIBUTES è presente solo in una risposta di errore quando il codice di risposta nell'attributo ERROR-CODE è 420.

L'attributo contiene un elenco di valori a 16 bit, ciascuno dei quali rappresenta un tipo di attributo che non è stato compreso dal server.

    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 ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figura 8: Formato dell'attributo UNKNOWN-ATTRIBUTES

Nota: In [RFC3489], questo campo era riempito a 32 duplicando l'ultimo attributo. In questa versione della specifica, vengono invece utilizzate le normali regole di padding per gli attributi.

15.10. SOFTWARE

L'attributo SOFTWARE contiene una descrizione testuale del software utilizzato dall'agente che invia il messaggio. È utilizzato da client e server. Il suo valore DOVREBBE includere produttore e numero di versione. L'attributo non ha impatto sul funzionamento del protocollo e serve solo come strumento per scopi diagnostici e di debug. Il valore di SOFTWARE è di lunghezza variabile. DEVE essere una sequenza codificata UTF-8 [RFC3629] di meno di 128 caratteri (che può essere lunga fino a 763 byte).

15.11. ALTERNATE-SERVER

Il server alternativo rappresenta un indirizzo di trasporto alternativo che identifica un diverso server STUN che il client STUN dovrebbe provare.

È codificato nello stesso modo di MAPPED-ADDRESS, e quindi fa riferimento a un singolo server tramite indirizzo IP. La famiglia di indirizzi IP DEVE essere identica a quella dell'indirizzo IP sorgente della richiesta.