54shuai / rfc5766-turn-server

Automatically exported from code.google.com/p/rfc5766-turn-server
0 stars 0 forks source link

Nonces not shared across allocations #107

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
RFC 5389 says that Nonce values are valid server-wide:

   If the client has not completed a successful request/response
   transaction with the server (as identified by hostname, if the DNS
   procedures of Section 9 are used, else IP address if not), it SHOULD
   omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
   In other words, the very first request is sent as if there were no
   authentication or message integrity applied.

   Once a request/response transaction has completed successfully, the
   client will have been presented a realm and nonce by the server, and
   selected a username and password with which it authenticated.  The
   client SHOULD cache the username, password, realm, and nonce for
   subsequent communications with the server.  When the client sends a
   subsequent request, it SHOULD include the USERNAME, REALM, and NONCE
   attributes with these cached values.  It SHOULD include a MESSAGE-
   INTEGRITY attribute, computed as described in Section 15.4 using the
   cached password.

However, rfc5766-turn-server nonce values appear to be scoped instead to the 
supersession, i.e. the client's sending IP and port.

What steps will reproduce the problem?
1. Create an allocation using long-term credentials: send a first request with 
no USERNAME, MESSAGE-INTEGRITY, REALM, or NONCE attributes; get a 401; re-send 
with those attributes.
2. Create another allocation (from a different endpoint port) with an ALLOCATE 
message containing the same USERNAME, REALM, and NONCE, and MESSAGE-INTEGRITY 
calculated using the same key.

What is the expected output? What do you see instead?

I expect the allocation to succeed.  Instead, I receive a 401 Unauthorized 
error. (Not even 438 Stale Nonce!)

What version of the product are you using? On what operating system?

This is turnserver-3.2.2.7, using Ubuntu 12.04.

Please provide any additional information below.

The specific use case I'm dealing with is creating a port pair (using EVEN-PORT 
/ RESERVATION-TOKEN).  The two allocations in the pair have to use different 
client ports.

Original issue reported on code.google.com by jonathan...@gmail.com on 18 Feb 2014 at 10:49

GoogleCodeExporter commented 9 years ago
No, there is no wording the RFC 5766 that mandates server-wide usage, you just 
implied that. The client can cache and re-use the nonce - but ONLY FOR THE SAME 
SESSION with the TURN server. The RFC 5766 does not require it to be used 
across the sessions. I agree that the words in the RFC are somewhat unclear; 
but for clarification we can check RFC 2617 that is referred to by RFC 5766:

http://tools.ietf.org/search/rfc2617#section-4.3

It is saying that: 

   "server is free to construct the nonce such that it may only be used
   from a particular client, for a particular resource, for a limited
   period of time or number of uses, or any other restrictions.  Doing
   so strengthens the protection provided against, for example, replay
   attacks".

We chose to make the nonce valid for only one session - because we can impose 
any limitation on the nonce (see "any other restriction" clause), per RFC 2617, 
and that is the limitation that makes it the most secure. And that must not be 
a problem for a clean client implementation.

Original comment by mom040...@gmail.com on 18 Feb 2014 at 11:08

GoogleCodeExporter commented 9 years ago
Oh, okay, I guess -- though that should be clarified in STUN-bis.

But if you want to do this, the error code if a super-session's initial request 
has invalid nonce (but a valid message-integrity) should be 438, not 401.  
Otherwise, this clause of 5389 applies:

   If the response is an error response with an error code of 401
   (Unauthorized), the client SHOULD retry the request with a new
   transaction.  [...]  The client MUST NOT perform this retry if it is
   not changing the USERNAME or REALM or its associated password, from
   the previous attempt.

I can file this as a new Issue if you want.

Original comment by jonathan...@gmail.com on 18 Feb 2014 at 11:16

GoogleCodeExporter commented 9 years ago
There is no practical way to distinguish between the case of wrong nonce and 
wrong integrity and the case of just wrong nonce. May be we can clarify that in 
stun bis but so far i see no problem.

Original comment by mom040...@gmail.com on 18 Feb 2014 at 11:26

GoogleCodeExporter commented 9 years ago
Huh? Isn't wrong nonce and correct integrity exactly what happens when a nonce 
expires? I'm just saying that the cases of "the session doesn't have a nonce 
yet" and "the session has a nonce, but it's expired" should be handled 
identically. Right now the former returns 401, and the latter returns 438.

Original comment by jonathan...@gmail.com on 18 Feb 2014 at 11:33

GoogleCodeExporter commented 9 years ago
No those are different cases. 

If we do not recognize nonce then we assign 438, as in rfc stale case.

Original comment by mom040...@gmail.com on 18 Feb 2014 at 11:44

GoogleCodeExporter commented 9 years ago
The algorithm is that:

1) If there is no username and/or no nonce and/or no realm in the message - 
then return 401.
2) If everything is there, but the nonce value is wrong - return 438 "stale 
nonce". We assume that the client just sent an expired realm. 
3) If INTEGRITY is wrong then return 401 for re-authentication.

There is no such case as "wrong nonce and correct integrity" because the 
integrity is calculated over nonce, too - so if the nonce is wrong then the 
integrity is wrong, too, automatically.

Original comment by mom040...@gmail.com on 18 Feb 2014 at 11:55

GoogleCodeExporter commented 9 years ago
That algorithm is correct, but it's not what the code actually does in all 
cases. If the super-session hasn't picked a nonce yet -- if ss->nonce[0] == 0 
-- the server returns 401, not 438, regardless of what attributes are present 
in the message.

By "wrong nonce and correct integrity" I meant integrity correctly calculated 
over a message that contains the wrong nonce.

Original comment by jonathan...@gmail.com on 19 Feb 2014 at 12:29

GoogleCodeExporter commented 9 years ago
If the nonce[0]==0 then we assume that the nonce has not been communicated
yet - that is 401 error. nonce[0]==0 means that we did not send nonce to
the client, yet. So whatever nonce is present in the message is totally
irrelevant. The nonce value in such a message is not "stale" - it is just
wrong because its origin is unknown and obscure. The "stale" error is about
the situation when in the middle of an already established valid session
the nonce value becomes invalid. If the session has not been established,
yet, then all problems are treated as 401 (need re-authentication) or 400
(incorrectly constructed messaged). That is the logic that we used.

Original comment by mom040...@gmail.com on 19 Feb 2014 at 12:37

GoogleCodeExporter commented 9 years ago
The problem with this logic is that if a client is interpreting the standard 
the way I did -- that nonces can be shared across allocations -- or if the 
turnserver crashes and restarts after an initial 401 response, the client will 
get a 401 for what it thinks is a valid nonce and username/realm/password.  
According to the quote from the STUN spec I quoted previously, it then MUST NOT 
resend the request if it's not changing the username/realm/password it's using.

What's wrong with sending 438 for an unknown nonce?

Original comment by jonathan...@gmail.com on 19 Feb 2014 at 3:15

GoogleCodeExporter commented 9 years ago
Ok i ll think what can be done.

But sharing the nonce between allocations is not a "standard way" - that was 
not a correct assumption. And the turn server must not crash.

I ll see if i can return 438 and what are the consequences.

Original comment by mom040...@gmail.com on 19 Feb 2014 at 4:10

GoogleCodeExporter commented 9 years ago
why i am return 400 wrong transport field!!!!

Original comment by jim.cao...@gmail.com on 3 Jul 2014 at 3:37