since people seemed to agree that s auth module is superior to k one, i decided to try porting k auth_radius module to use s auth api and was able to compile and build it against s auth api.
when testing the result, i get errors about "unknown command, missing loadmodule" when script has proxy_challenge() call.
i then went and checked s auth module and found this in README:
1.4.2. proxy_challenge(realm, qop)
The function challenges a user agent. ...
however, auth_mod.c does not include such function:
/* * Exported functions */ static cmd_export_t cmds[] = { {"consume_credentials", consume_credentials, 0, 0, REQUEST_ROUTE}, {"bind_auth_s", (cmd_function)bind_auth_s, 0, 0, 0 }, {0, 0, 0, 0, 0} };
i don't find it even with grep on s modules. where is it?
-- juha
Juha,
On Thu, Jul 1, 2010 at 12:19 PM, Juha Heinanen jh@tutpro.com wrote:
since people seemed to agree that s auth module is superior to k one, i decided to try porting k auth_radius module to use s auth api and was able to compile and build it against s auth api.
when testing the result, i get errors about "unknown command, missing loadmodule" when script has proxy_challenge() call.
i then went and checked s auth module and found this in README:
1.4.2. proxy_challenge(realm, qop)
The function challenges a user agent. ...
however, auth_mod.c does not include such function:
/* * Exported functions */ static cmd_export_t cmds[] = { {"consume_credentials", consume_credentials, 0, 0, REQUEST_ROUTE}, {"bind_auth_s", (cmd_function)bind_auth_s, 0, 0, 0 }, {0, 0, 0, 0, 0} };
i don't find it even with grep on s modules. where is it?
It has been obsoleted because all the function did was to send a reply with digest challenge included. We achieve the same in the configuration file with a combination of append_to_reply and sl_reply:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) { if ($? == -2) { sl_reply("500", "Internal Server Error"); } else if ($? == -3) { sl_reply("400", "Bad Request"); } else { if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); } sl_reply("407", "Proxy Authentication Required"); } drop; }
-Jan
Jan Janak writes:
It has been obsoleted because all the function did was to send a reply with digest challenge included. We achieve the same in the configuration file with a combination of append_to_reply and sl_reply:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) { if ($? == -2) { sl_reply("500", "Internal Server Error"); } else if ($? == -3) { sl_reply("400", "Bad Request"); } else { if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); } sl_reply("407", "Proxy Authentication Required"); } drop; }
jan,
thanks for the explanation. what value should i give to $digest_challenge variable so that proper Proxy-Authenticate header is included in the reply?
-- juha
On Thu, Jul 1, 2010 at 2:18 PM, Juha Heinanen jh@tutpro.com wrote:
Jan Janak writes:
It has been obsoleted because all the function did was to send a reply with digest challenge included. We achieve the same in the configuration file with a combination of append_to_reply and sl_reply:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) { if ($? == -2) { sl_reply("500", "Internal Server Error"); } else if ($? == -3) { sl_reply("400", "Bad Request"); } else { if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); } sl_reply("407", "Proxy Authentication Required"); } drop; }
jan,
thanks for the explanation. what value should i give to $digest_challenge variable so that proper Proxy-Authenticate header is included in the reply?
The whole header field, including the header field name and terminating CRLF. The function build_challenge_hf in modules_s/challenge.c can do this for you. The auth module exports the function through its API so you can easily reuse it.
See the function "authenticate" in modules_s/auth_db/authorize.c for an example, grep for the string "build_challenge".
-Jan
Jan Janak writes:
See the function "authenticate" in modules_s/auth_db/authorize.c for an example, grep for the string "build_challenge".
jan,
i see that this thing in the code builds the challenge (p-a header):
if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; }
is there a way to prevent p-a header from being added to reply in case after proxy_authorize failure i want to reply with "403 Forbidden" instead of "407 Proxy Authentication Required"?
-- juha
Juha Heinanen writes:
i see that this thing in the code builds the challenge (p-a header):
if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; }
is there a way to prevent p-a header from being added to reply in case after proxy_authorize failure i want to reply with "403 Forbidden" instead of "407 Proxy Authentication Required"?
jan,
i was able to figure this out. auth_api.build_challenge stores the header in a variable that defaults to $digest_challenge. however, when i write in config file as you suggested:
if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); }; send_reply("407", "Proxy Authentication Required");
i get these errors to syslog:
Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [mod_fix.c:246]: Cannot convert function parameter 1 to0 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1019 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1020 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1023 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1042
what does % mean in "%$digest_challenge"?
-- juha
Juha Heinanen writes:
i write in config file as you suggested:
if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); }; send_reply("407", "Proxy Authentication Required");
i get these errors to syslog:
Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [mod_fix.c:246]: Cannot convert function parameter 1 to0 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1019 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1020 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1023 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1042
what does % mean in "%$digest_challenge"?
jan,
i was able to make sr happy by writing the digest_challenge stuff like this:
if (defined($avp(digest_challenge)) && ($avp(digest_challenge) != "")) { append_to_reply("$avp(digest_challenge)"); };
now i'll continue with tests.
-- juha
On Thu, Jul 1, 2010 at 3:30 PM, Juha Heinanen jh@tutpro.com wrote:
Juha Heinanen writes:
i see that this thing in the code builds the challenge (p-a header):
if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; }
is there a way to prevent p-a header from being added to reply in case after proxy_authorize failure i want to reply with "403 Forbidden" instead of "407 Proxy Authentication Required"?
jan,
i was able to figure this out. auth_api.build_challenge stores the header in a variable that defaults to $digest_challenge. however, when i write in config file as you suggested:
if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); }; send_reply("407", "Proxy Authentication Required");
i get these errors to syslog:
Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [mod_fix.c:246]: Cannot convert function parameter 1 to0 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1019 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1020 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1023 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1042
what does % mean in "%$digest_challenge"?
Ohh, that is the syntax used by the xlog module. Behind the scenes, the function append_to_reply calls a function from xlog module to expand variable names in the string to corresponding values and then the resulting string is appended to the reply.
Please load the xlog module and try again. I realize that requiring xlog module for this type of stuff isn't particularly nice, but it is a temporary solution until we have support for real "formatted" strings, i.e., strings where occurrences of variables, PVs and selects will be expanded transparently.
-Jan
Jan Janak writes:
Please load the xlog module and try again. I realize that requiring xlog module for this type of stuff isn't particularly nice, but it is a temporary solution until we have support for real "formatted" strings, i.e., strings where occurrences of variables, PVs and selects will be expanded transparently.
jan,
i'm already using k xlog module. does the avp syntax that i showed in the previous message look good to you? at least sr likes it.
-- juha
On Thu, Jul 1, 2010 at 4:00 PM, Juha Heinanen jh@tutpro.com wrote:
Jan Janak writes:
Please load the xlog module and try again. I realize that requiring xlog module for this type of stuff isn't particularly nice, but it is a temporary solution until we have support for real "formatted" strings, i.e., strings where occurrences of variables, PVs and selects will be expanded transparently.
jan,
i'm already using k xlog module. does the avp syntax that i showed in the previous message look good to you? at least sr likes it.
Yes, seems fine to me. Either should work.
-Jan
On Jul 01, 2010 at 22:30, Juha Heinanen jh@tutpro.com wrote:
Juha Heinanen writes:
i see that this thing in the code builds the challenge (p-a header):
if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; }
is there a way to prevent p-a header from being added to reply in case after proxy_authorize failure i want to reply with "403 Forbidden" instead of "407 Proxy Authentication Required"?
jan,
i was able to figure this out. auth_api.build_challenge stores the header in a variable that defaults to $digest_challenge. however, when i write in config file as you suggested:
if (defined $digest_challenge && $digest_challenge != "") { append_to_reply("%$digest_challenge"); }; send_reply("407", "Proxy Authentication Required");
i get these errors to syslog:
Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [mod_fix.c:246]: Cannot convert function parameter 1 to0 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1019 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1020 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1023 Jul 1 22:24:54 localhost /usr/sbin/sip-proxy[26750]: ERROR: <core> [route.c:1088]: fixing failed (code=-1) at cfg:/etc/sip-proxy/sip-proxy.cfg:1042
what does % mean in "%$digest_challenge"?
That's used for passing format string to ser textops/append_to_reply. It means what follows should be interpreted in a special way (avp, select, xlog format). E.g.: append_to_reply("Foo: %$my_var \n\r");
If you use k textops skip the "%" (you should be able to use directly $digest_challenge).
Andrei
On Thu, Jul 1, 2010 at 3:13 PM, Juha Heinanen jh@tutpro.com wrote:
Jan Janak writes:
See the function "authenticate" in modules_s/auth_db/authorize.c for an example, grep for the string "build_challenge".
jan,
i see that this thing in the code builds the challenge (p-a header):
if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; }
is there a way to prevent p-a header from being added to reply in case after proxy_authorize failure i want to reply with "403 Forbidden" instead of "407 Proxy Authentication Required"?
Yes. The function only creates the corresponding AVP, it does not add anything to the reply itself. This is done in the configuration file and there you can test the return value of proxy_authorize and either send "403 Forbidden" or "407 Proxy Authorization Required".
So, you can return any reply you want, the proxy authorization header will only be added if you call append_to_reply("%$digest_challenge");
-Jan
jan,
since vars are faster than avps, i defined:
modparam("auth", "challenge_attr", "$var(digest_challenge)")
but it didn't work. looks like parse_avp_ident function does not support vars:
* Parses the following avp indentifier forms: * - "i:<number>" - old form, deprecated (e.g. i:42) * - "s:<string>" - old form, deprecated (e.g. s:foo) * - "<track>.<name>" (e.g.: f.bar) * - "<track>.<name>[<index>]" (e.g.: f.bar[1]) * - "<track><class>.<name>" (e.g: tu.bar) * - "<track><class>.<name>[<index>]" (e.g: fd.bar[2]) * - "<string>" (e.g.: foo)
is there something like k vars in s?
-- juha
2010/7/1 Juha Heinanen jh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
On Thu, Jul 1, 2010 at 3:31 PM, Iñaki Baz Castillo ibc@aliax.net wrote:
2010/7/1 Juha Heinanen jh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
A variable containing the string to be used as realm in digest authentication. In most circumstances its value is retrieved from the database (domain_attrs table).
-Jan
2010/7/1 Jan Janak jan@ryngle.com:
On Thu, Jul 1, 2010 at 3:31 PM, Iñaki Baz Castillo ibc@aliax.net wrote:
2010/7/1 Juha Heinanen jh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
A variable containing the string to be used as realm in digest authentication. In most circumstances its value is retrieved from the database (domain_attrs table).
So, if for example the From domain is "example.org" then SER would search for the realm corresponding to the domain "example.org" (which could be the domain itself or any other token), am I right?
I like it, more than the "subscriber" table and the "auth_db" module of Kamailio. Let me explain why:
- Imagine a Kamailio in multidomain mode.
- A phone "sip:alice@example.org" sends an INVITE with "From: sip:anonymous@invalid-domain.org" (so the user requests for privacy).
- The INVITE doesn't have a "P-Preferred-Identity: sip:alice@example.org" (it doesn't implement RFC 3325).
- So, how could Kamailio ask for authentication? which realm to use? there is no string in the INVITE identyfing the domain the originator belongs to, so...
The only solution for this issue would be using the same realm for every users and domain of the proxy, but in Kamailio this is not possible if "calculate_ha1" (in "auth_db") is 0 because Kamailio takes the realm of the request to look for the corresponding user using such realm as domain.
With SER the above problem would be solved by using the same realm for all the users and domains, but with a constrain: the "username" field of the creedentials generated by the user should be a full URI "sip:alice@example.org" (or perhaps also "alice@example.org"), so the auth module would parse the username and domain from the credentials "username" field.
In a future I would like to talk about the credentials username field format (just SIP username, username@domain or sip:username@domain) in a future. IMHO in a multidomain system phones should authenticate themself by using the whole AoR (including the "sip:" schema) in the "username" field of the credentials.
Regards.
On 7/1/10 9:50 PM, Iñaki Baz Castillo wrote:
2010/7/1 Jan Janakjan@ryngle.com:
On Thu, Jul 1, 2010 at 3:31 PM, Iñaki Baz Castilloibc@aliax.net wrote:
2010/7/1 Juha Heinanenjh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
A variable containing the string to be used as realm in digest authentication. In most circumstances its value is retrieved from the database (domain_attrs table).
So, if for example the From domain is "example.org" then SER would search for the realm corresponding to the domain "example.org" (which could be the domain itself or any other token), am I right?
I like it, more than the "subscriber" table and the "auth_db" module of Kamailio. Let me explain why:
Imagine a Kamailio in multidomain mode.
A phone "sip:alice@example.org" sends an INVITE with "From:
sip:anonymous@invalid-domain.org" (so the user requests for privacy).
- The INVITE doesn't have a "P-Preferred-Identity:
sip:alice@example.org" (it doesn't implement RFC 3325).
- So, how could Kamailio ask for authentication? which realm to use?
there is no string in the INVITE identyfing the domain the originator belongs to, so...
just use pv_proxy/www_authorize() from k auth module and you can pass username/password fetched from where you want and how you want.
Cheers, Daniel
The only solution for this issue would be using the same realm for every users and domain of the proxy, but in Kamailio this is not possible if "calculate_ha1" (in "auth_db") is 0 because Kamailio takes the realm of the request to look for the corresponding user using such realm as domain.
With SER the above problem would be solved by using the same realm for all the users and domains, but with a constrain: the "username" field of the creedentials generated by the user should be a full URI "sip:alice@example.org" (or perhaps also "alice@example.org"), so the auth module would parse the username and domain from the credentials "username" field.
In a future I would like to talk about the credentials username field format (just SIP username, username@domain or sip:username@domain) in a future. IMHO in a multidomain system phones should authenticate themself by using the whole AoR (including the "sip:" schema) in the "username" field of the credentials.
Regards.
2010/7/1 Daniel-Constantin Mierla miconda@gmail.com:
- So, how could Kamailio ask for authentication? which realm to use?
there is no string in the INVITE identyfing the domain the originator belongs to, so...
just use pv_proxy/www_authorize() from k auth module and you can pass username/password fetched from where you want and how you want.
Good point. Thanks :)
On Thu, Jul 1, 2010 at 3:50 PM, Iñaki Baz Castillo ibc@aliax.net wrote:
2010/7/1 Jan Janak jan@ryngle.com:
On Thu, Jul 1, 2010 at 3:31 PM, Iñaki Baz Castillo ibc@aliax.net wrote:
2010/7/1 Juha Heinanen jh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
A variable containing the string to be used as realm in digest authentication. In most circumstances its value is retrieved from the database (domain_attrs table).
So, if for example the From domain is "example.org" then SER would search for the realm corresponding to the domain "example.org" (which could be the domain itself or any other token), am I right?
Right. Basically this is a generalization of how realms used to be handled in SER. You can set the realm to the domain name itself (preserving the original functionality), you can set it to a completelly different value, you can share realms among multiple virtual domains, and so on.
In most cases you want the realm to be the same as the domain name itself, but there are legitimate cases where this isn't sufficient and we wanted to make sure that we could support such cases properly.
I like it, more than the "subscriber" table and the "auth_db" module of Kamailio. Let me explain why:
Imagine a Kamailio in multidomain mode.
A phone "sip:alice@example.org" sends an INVITE with "From:
sip:anonymous@invalid-domain.org" (so the user requests for privacy).
- The INVITE doesn't have a "P-Preferred-Identity:
sip:alice@example.org" (it doesn't implement RFC 3325).
- So, how could Kamailio ask for authentication? which realm to use?
there is no string in the INVITE identyfing the domain the originator belongs to, so...
The only solution for this issue would be using the same realm for every users and domain of the proxy, but in Kamailio this is not possible if "calculate_ha1" (in "auth_db") is 0 because Kamailio takes the realm of the request to look for the corresponding user using such realm as domain.
Yes.
With SER the above problem would be solved by using the same realm for all the users and domains, but with a constrain: the "username" field of the creedentials generated by the user should be a full URI "sip:alice@example.org" (or perhaps also "alice@example.org"), so the auth module would parse the username and domain from the credentials "username" field.
And this too can already be done, you can simply set the value of the digest_realm variable with something like:
$f.digest_realm = @authorization[...].username.domain
before calling proxy_authenticate. Any part of the SIP message can be used to set digest realm.
Note that this would also work with calc_ha1 set to 0. The subscriber table contains a column called ha1b which is used when the UA supplies digest username of form "user@domain". All you need to do make the auth_db module use that column instead of ha1 with a modparam.
In a future I would like to talk about the credentials username field format (just SIP username, username@domain or sip:username@domain) in a future. IMHO in a multidomain system phones should authenticate themself by using the whole AoR (including the "sip:" schema) in the "username" field of the credentials.
All this can be supported today with authentication modules coming from SER in sip-router.
-Jan
2010/7/1 Jan Janak jan@ryngle.com:
With SER the above problem would be solved by using the same realm for all the users and domains, but with a constrain: the "username" field of the creedentials generated by the user should be a full URI "sip:alice@example.org" (or perhaps also "alice@example.org"), so the auth module would parse the username and domain from the credentials "username" field.
And this too can already be done, you can simply set the value of the digest_realm variable with something like:
$f.digest_realm = @authorization[...].username.domain
Could you please detail more this code? Let me set an example:
1) SR multidomain and two users:
- sip:alice@dom1.org - realm = "myserver.org" - sip:alice@dom2.org - realm = "myserver.org"
2) An INVITE arrives sent by alice@dom1.org:
INVITE sip:bob@dom3.org SIP/2.0 From: sip:anonymous@invalid-domain.org
3) SR asks for authentication using the shared realm "myserver.org".
4) Let's imagine the UAC sets credentials in these ways:
4.1) Digest realm="myserver.org", username="alice" 4.2) Digest realm="myserver.org", username="alice@dom1.org" 4.3) Digest realm="myserver.org", username="sip:alice@dom1.org"
So, option 4.1 wouldn't clarify if the authenticated user is "sip:alice@dom1.org" or "sip:alice@dom2.org". This is, if the UAC just sets its AoR username in the credentials 'username' field then the above case cannot work as it would require the proxy using a different realm = domain and the INVITE request to contain the domain somewhere (i.e. P-Preferred-Identity header which is not the case).
Option 4.2 would work as from the credentials the proxy can identity "sip:alice@dom1.org", but IMHO the credentials username format should be an AoR (with the schema).
Options 4.3 seems the best one for me, but not sure if it's feasible with the currently existing UA's.
before calling proxy_authenticate. Any part of the SIP message can be used to set digest realm.
The problem is that in the above INVITE there is no way to choose the realm based on the SIP headers.
Note that this would also work with calc_ha1 set to 0. The subscriber table contains a column called ha1b which is used when the UA supplies digest username of form "user@domain".
Yes, but would it work in case of "sip:user@domain"?
Thanks a lot.
On Thu, Jul 1, 2010 at 6:01 PM, Iñaki Baz Castillo ibc@aliax.net wrote:
2010/7/1 Jan Janak jan@ryngle.com:
With SER the above problem would be solved by using the same realm for all the users and domains, but with a constrain: the "username" field of the creedentials generated by the user should be a full URI "sip:alice@example.org" (or perhaps also "alice@example.org"), so the auth module would parse the username and domain from the credentials "username" field.
And this too can already be done, you can simply set the value of the digest_realm variable with something like:
$f.digest_realm = @authorization[...].username.domain
Could you please detail more this code? Let me set an example:
Sorry, I don't have an example at hand, it's been a while since I worked on this.
- SR multidomain and two users:
- sip:alice@dom1.org - realm = "myserver.org" - sip:alice@dom2.org - realm = "myserver.org"
- An INVITE arrives sent by alice@dom1.org:
INVITE sip:bob@dom3.org SIP/2.0 From: sip:anonymous@invalid-domain.org
SR asks for authentication using the shared realm "myserver.org".
Let's imagine the UAC sets credentials in these ways:
4.1) Digest realm="myserver.org", username="alice" 4.2) Digest realm="myserver.org", username="alice@dom1.org" 4.3) Digest realm="myserver.org", username="sip:alice@dom1.org"
So, option 4.1 wouldn't clarify if the authenticated user is "sip:alice@dom1.org" or "sip:alice@dom2.org". This is, if the UAC just sets its AoR username in the credentials 'username' field then the above case cannot work as it would require the proxy using a different realm = domain and the INVITE request to contain the domain somewhere (i.e. P-Preferred-Identity header which is not the case).
This seems correct to me.
An alternative solution would be making the username 'alice' unique across all domains supported on the server. Then you could deduce the virtual domain from the username. Although feasible, this scenario is not common and I mention it just for completeness.
Option 4.2 would work as from the credentials the proxy can identity "sip:alice@dom1.org", but IMHO the credentials username format should be an AoR (with the schema).
Whether or not the schema should be included is something we can argue about, but in the end it does not really matter because it is not standard anyway. You can choose whichever way you like more and what your UAs support.
Options 4.3 seems the best one for me, but not sure if it's feasible with the currently existing UA's.
If the UA allows you to enter the username for digest authentication explicitly then it probably will be supported. In fact, from what I have seen on iptel.org, this is quite common configuration mistake.
The column ha1b in the subscriber table exists exactly for this case. That is, if you have calc_ha1 disabled and the UA sends a username with '@' in it, SR automatically uses the column ha1b instead of ha1. The difference between ha1 and ha1b is that the hash in ha1b is calculated as MD5(username@realm:realm:password), while ha1 is calculated as MD5(username:realm:password). So you've got both cases covered and you can still disable calculate_ha1.
before calling proxy_authenticate. Any part of the SIP message can be used to set digest realm.
The problem is that in the above INVITE there is no way to choose the realm based on the SIP headers.
If there is nothing that identifies the domain then there isn't much you can do. Though I've seen UAs that send "empty" digest credentials with just username and no nonce or response attributes, that could be used in such case.
Note that this would also work with calc_ha1 set to 0. The subscriber table contains a column called ha1b which is used when the UA supplies digest username of form "user@domain".
Yes, but would it work in case of "sip:user@domain"?
I am not sure, you'll need to check the code. I wrote that part 8 years ago and I don't remember if I check for the presence of scheme. ;-).
-Jan
2010/7/2 Jan Janak jan@ryngle.com:
If there is nothing that identifies the domain then there isn't much you can do. Though I've seen UAs that send "empty" digest credentials with just username and no nonce or response attributes, that could be used in such case.
Really exotic :)
Note that this would also work with calc_ha1 set to 0. The subscriber table contains a column called ha1b which is used when the UA supplies digest username of form "user@domain".
Yes, but would it work in case of "sip:user@domain"?
I am not sure, you'll need to check the code. I wrote that part 8 years ago and I don't remember if I check for the presence of scheme. ;-).
I did some tests and it didn't work for me (but neither using user@domain without schema, so I think it was my fault...).
Thanks.
Iñaki Baz Castillo writes:
2010/7/1 Juha Heinanen jh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
i guess is if realm of from user. i just use $var(from_uri_domain) to which i have assigned the same thing.
-- juha
On Jul 01, 2010 at 21:31, Iñaki Baz Castillo ibc@aliax.net wrote:
2010/7/1 Juha Heinanen jh@tutpro.com:
if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
What is $fd.digest_realm ?
It's a domain level avp (the 'd' in fd), from the caller avp list (the 'f'), named digest_realm.
If you write only $digest_realm then this is a shorcut for $f.digest_realm. If there is no user level avp defined with this name ($fu.digest_realm does not exist), the $f.digest_realm == $fd.digest_realm (the value from the domain list is used). So if you don't have any $f*.digest_realm defined, the above is equivalent with $digest_realm.
For more info about the different avp lists, levels (uri, user, domain and global) and how they are selected, see: http://sip-router.org/wiki/devel/avps-ser
Andrei