Summary:ASTERISK-22386: Outbound SIP registration, if the auth object's realm option is not set to the same value as the 401's realm, then we fail to create a new REGISTER with auth details
Reporter:Rusty Newton (rnewton)Labels:
Date Opened:2013-08-25 17:13:01Date Closed:2013-09-13 09:34:03
Status:Closed/CompleteComponents:Resources/res_pjsip Resources/res_pjsip_outbound_authenticator_digest
Versions:12 Frequency of
Environment:SVN-branch-12-r397614M (with patch from ASTERISK-22380)Attachments:( 0) full10.txt
( 1) full11.txt
( 2) outbound_auth_realm_v2.patch
( 3) pjsip10.txt
( 4) pjsip11.txt
Description:Without "realm=<somevalue>" defined we see

[Aug 25 16:57:54] WARNING[21069]: res_pjsip_outbound_authenticator_digest.c:90 digest_create_request_with_auth: Failed to create new request with authentication credentials
[Aug 25 16:57:54] WARNING[21069]: res_pjsip_outbound_registration.c:387 handle_registration_response: Temporal response '401' received from 'sip:gw1.sip.us' on registration attempt to 'sip:5279938664@gw1.sip.us', retrying in '15' seconds

after the 401 in an outbound REGISTER dialog. The WARNING messages don't really make it clear why we fail to create a new request.

I'll attach a working and non-working example to make it clear. For Asterisk to issue a new REGISTER request with Authentication I had to define realm specifically with the value we see in the 401's WWW-Authenticate header.

*In the failing config pjsip10.txt, realm is undefined. The same failure mode occurs with realm defined, but not set specifically to the realm value from the challenge.*

I'm not sure what the solution here is.

* It looks like a bug that we *don't* create a new REGISTER without realm specifically defined
* If it is legit that we are failing out here, can the WARNING be made to detail the issue?
* Should we be responding with the default realm of "asterisk" or should we be responding using the realm in the challenge if we don't define it specifically in config?
Comments:By: Rusty Newton (rnewton) 2013-08-25 17:26:40.059-0500

Failing debug and config:  full10 and pjsip10

By: Rusty Newton (rnewton) 2013-08-25 17:31:57.159-0500

Working debug and config: full11.txt and pjsip11.txt

By: Rusty Newton (rnewton) 2013-08-25 17:37:32.095-0500

Maybe another option for our possible behavior:


bq. If no credentials for a realm can be located, UACs MAY attempt to retry the request with a username of "anonymous" and no password (a password of "").

Though that is overlooking the fact that realm should be set to "asterisk" by default.

By: George Joseph (gjoseph) 2013-09-03 16:46:36.733-0500

I'm actually working on a patch for this.

Adding a function to res_pjsip_outbound_registration.c that finds the proxy or www authenticate header.
In set_outbound_authentication_credentials, substitute the realm from the header if the auth config object's realm is null.

By: George Joseph (gjoseph) 2013-09-03 17:03:57.356-0500

Actually, need a little guidance here...

Shouldn't the realm ALWAYS be set to the realm of the challenge in the context of an outbound invite or register?
It would be a guaranteed failure if it wasn't.

So basically the realm from the auth object should ALWAYS be overridden in the context of an outbound request, no?

If we don't override, how can we tell if the realm from the auth object was set to "asterisk" or just defaulted to "asterisk"?

By: George Joseph (gjoseph) 2013-09-03 19:21:47.428-0500

This patch forces the realm used in outbound requests to match that of the challenge sent by the peer in a 401 or 407 response.

EDIT:  Tested with 401 responses on outbound registers and invites.  Needs to be tested with 407 (proxy) responses.

By: George Joseph (gjoseph) 2013-09-03 23:27:54.845-0500

v2 of this patch replaces the hard coded 401 and 407 response codes with their proper PJSIP defines.

By: Mark Michelson (mmichelson) 2013-09-04 17:13:31.170-0500

Thanks for the patch! Unfortunately, my inclination is that your approach is not correct for the given problem. The idea behind realm-based authentication is not to always match a realm given in the 401/407. Instead, the intention is to present credentials that match any realms in the 401/407. So in Rusty's original case, it is 100% correct that we could not create a request with authentication credentials since we did not have credentials for the realm presented in the 401. As Rusty stated, this isn't an error in the code, it was a user error and the output should have made it more clear why a request with authentication credentials could not be created.

Now, that being said, there may be some merit to defining the idea of a "wildcard" option for realms in auth sections. So for instance, if we were asked for credentials for a particular realm, then an auth section with a wildcard realm could do as your patch does and match any realm presented in the 401/407. However, this would need to be a separate issue and would be a new feature rather than a bug fix.

By: Mark Michelson (mmichelson) 2013-09-04 17:33:46.742-0500

I've committed a change to Asterisk 12 (revision 398299) that gives further details in the warning messages than was previously given. In my previous comment, I mostly spoke regarding the patch on the issue. Let me answer the three questions from the original description:

1) It's not a bug that we don't create a new REGISTER. If we don't have credentials that match the realm in the 401, then we can't attempt to authenticate. By the way, if no realm is given in an auth section, the realm defaults to the value "asterisk".
2) The commit I pointed out at the beginning of this comment should give better warning messages.
3) We should not respond with a default realm or mirror the one in the challenge. Instead, we can only provide credentials for realms we have credentials for.

Even though I have committed a fix for this, I'm leaving the issue open for now just in case I get proven wrong about what behavior should be here. Either way, the finer-grained warning messages are needed.

By: George Joseph (gjoseph) 2013-09-04 17:41:17.801-0500

Well, missing feature or bug right now it's NOT acceptable to have to specify the exact realm for an outbound request regardless of the error message.  chan_sip figures it out.  Imagine if a web browser user agent had to do that. :)  

Anyway, if I create a new feature and attach a modified patch that only does the substitution if the realm in the auth config object was '*' would that be acceptable?

By: Mark Michelson (mmichelson) 2013-09-04 18:13:41.723-0500

I had a talk with file on IRC, and he brought up the idea that no provided realm should be considered a wildcard realm as I proposed two comments ago. With that in mind, the patch provided would be a good first step, it just would need to be modified in the following ways:

1) It would need to modify res/res_pjsip/config_auth.c to not set "asterisk" as the default realm for auth sections.
2) It would need to account for the fact that more than one WWW-Authenticate or Proxy-Authenticate header may be present in an incoming 401/407.
3) It would only need to match the realm of a WWW-Authenticate or Proxy-Authenticate header if the configured auth did not have a realm set on it.
4) res/res_pjsip_authenticator_digest.c (the module that sends authentication challenges) would need to provide a default realm value for auths that do not have a realm set.

By: George Joseph (gjoseph) 2013-09-04 18:49:30.869-0500

1)  Gotcha.
2)  Yeah, pjsip_auth_clt_reinit_req does this but in a different context.  Since all we're doing here is searching for a realm not constructing the response, what do you want the behavior to be if there's more than 1 header and the unlikely case that the realms are different?  Practically speaking, for the same realm, the only difference in the headers should be the scheme (which doesn't matter in this context) but different realms???
3)  Gotcha.
4)  Gotcha.

To paraphrase...
When the auth object is used to send challenges, a default of "asterisk" will be used if one isn't specified.
When the auth object is used to send responses, a default of the challenge's realm will be used if one isn't specified.
In both cases, if a realm is specified in the config it is always used.

By: Mark Michelson (mmichelson) 2013-09-05 09:21:01.609-0500

Your paraphrase sums it up well.

I think point 2) can be dropped entirely, because it appears that PJSIP only will try to authenticate for the top-most WWW-Authenticate/Proxy-Authenticate header anyway. So even if we tried to be diligent and account for multiple realms (which as you pointed out is incredibly unlikely in the first place) it wouldn't do us any good.

By: George Joseph (gjoseph) 2013-09-05 15:32:00.863-0500

Created improvement ASTERISK-22471
New patch attached there.