Folks,
I am correct that it is impossible to use uri==myself check along with record_route()? That is, consider the following situation:
UA1->SER (with record_route())->UA2
UA1 sends INVITE to SER:
INVITE sip:ua2@ser.ip Contact: sip:ua1@ua1.ip
After processing SER resends it to UA2:
INVITE sip:ua2@ua2.ip Record-Route: sip:ua2@ser.ip;lr Contact: sip:ua1@ua1.ip
Then, if UA2 wishes to terminate session it sends the following BYE to the SER:
BYE sip:ua1@ua1.ip Route: sip:ua2@ser.ip;lr Contact: sip:ua2@ua2.ip
Therefore if there any
if (!(uri==myself)) { sl_send_reply("500", "example serves only my domain"); break; };
checks in the SER, it will reply with 500 to UA2, not allowing transaction to go through.
-Maxim
On 22-10 21:50, Maxim Sobolev wrote:
Folks,
I am correct that it is impossible to use uri==myself check along with record_route()? That is, consider the following situation:
UA1->SER (with record_route())->UA2
UA1 sends INVITE to SER:
INVITE sip:ua2@ser.ip Contact: sip:ua1@ua1.ip
After processing SER resends it to UA2:
INVITE sip:ua2@ua2.ip Record-Route: sip:ua2@ser.ip;lr Contact: sip:ua1@ua1.ip
Then, if UA2 wishes to terminate session it sends the following BYE to the SER:
BYE sip:ua1@ua1.ip Route: sip:ua2@ser.ip;lr Contact: sip:ua2@ua2.ip
Therefore if there any
if (!(uri==myself)) { sl_send_reply("500", "example serves only my domain"); break; };
checks in the SER, it will reply with 500 to UA2, not allowing transaction to go through.
That is correct. Mid-dialog requests (like BYE) must not be processed in the if (uri==myself) section, you just need to relay them.
The problem in your config file is that you reject anything that doesn't match (uri==myself), you should just t_relay such messages (yes I know it creates open relay).
Determining what should be relayed and what not in this case is another story (since you probably doesn't want to be open relay). (Digest authentication doesn't help here much).
Jan.
Jan Janak wrote:
On 22-10 21:50, Maxim Sobolev wrote:
Folks,
I am correct that it is impossible to use uri==myself check along with record_route()? That is, consider the following situation:
UA1->SER (with record_route())->UA2
UA1 sends INVITE to SER:
INVITE sip:ua2@ser.ip Contact: sip:ua1@ua1.ip
After processing SER resends it to UA2:
INVITE sip:ua2@ua2.ip Record-Route: sip:ua2@ser.ip;lr Contact: sip:ua1@ua1.ip
Then, if UA2 wishes to terminate session it sends the following BYE to the SER:
BYE sip:ua1@ua1.ip Route: sip:ua2@ser.ip;lr Contact: sip:ua2@ua2.ip
Therefore if there any
if (!(uri==myself)) { sl_send_reply("500", "example serves only my domain"); break; };
checks in the SER, it will reply with 500 to UA2, not allowing transaction to go through.
That is correct. Mid-dialog requests (like BYE) must not be processed in the if (uri==myself) section, you just need to relay them.
The problem in your config file is that you reject anything that doesn't match (uri==myself), you should just t_relay such messages (yes I know it creates open relay).
Determining what should be relayed and what not in this case is another story (since you probably doesn't want to be open relay). (Digest authentication doesn't help here much).
That the problem I am trying to solve. Having my system working as an open relay is the idea that thrives me a lot. :-(
-Maxim
On 22-10 22:36, Maxim Sobolev wrote:
That is correct. Mid-dialog requests (like BYE) must not be processed in the if (uri==myself) section, you just need to relay them.
The problem in your config file is that you reject anything that doesn't match (uri==myself), you should just t_relay such messages (yes I know it creates open relay).
Determining what should be relayed and what not in this case is another story (since you probably doesn't want to be open relay). (Digest authentication doesn't help here much).
That the problem I am trying to solve. Having my system working as an open relay is the idea that thrives me a lot. :-(
We discussed this some time ago, part of it is already implemented, Juha started to implement another part, but I don't know what is the current state.
Here is a description:
Before forwarding a mid-dialog request, a proxy would like to check that the dialog has been established using the proxy. To be able to do that, a piece information has to be inserted into INVITE message that can later help to identify the dialog. The only place in the SIP message where this can be done is Record-Route header field (because you can make sure that the the contents of the header field will be present in all subsequent requests).
The proxy will mark the dialog by inserting ftag parameter into it's Record-Route header field, the ftag parameter will contain From tag.
Later, when a mid-dialog request (for example BYE) comes, the proxy will do the following:
- First it checks if From contains a domain the proxy is responsible for and if so, it will simply generate digest challenge and that's it. If the user is able to generate proper digest reply than he belongs to our domain and his requests will be forwarded.
- If From doesn't contain a domain the proxy is responsible from then we can't use digest authentication--the sender wouldn't be able to generate proper reply.
In this case the proxy compares To tag with ftag parameter value from it's Route header field. If they are same then the dialog was established using the proxy and we are done -- we can relay the request.
The algorithm will also work with messages which do not establish a dialog like MESSAGE or OPTIONS because such message will have domain of our proxy either in From (we challenge) or in the Request-URI (processed automatically).
Current implementation status is that the ftag part has already been implemented and Juha recently sent a message that he is working on a function that can do the comparison with To tag.
The approach as described here won't prevent malicious users from using your proxy as a relay because they can forge the Route header field including ftag parameter, but it will prevent users that have "misconfigured" their user agents from using you as outbound proxy.
To prevent also malicious users, some kind of cryptographic protection of the Route header field would be needed.
This cryptographic protection is already implemented, but I have it in form of a patch and I haven't enough time yet to integrate and test it.
Jan.
Jan Janak wrote:
On 22-10 22:36, Maxim Sobolev wrote:
That is correct. Mid-dialog requests (like BYE) must not be processed in the if (uri==myself) section, you just need to relay them.
The problem in your config file is that you reject anything that doesn't match (uri==myself), you should just t_relay such messages (yes I know it creates open relay).
Determining what should be relayed and what not in this case is another story (since you probably doesn't want to be open relay). (Digest authentication doesn't help here much).
That the problem I am trying to solve. Having my system working as an open relay is the idea that thrives me a lot. :-(
We discussed this some time ago, part of it is already implemented, Juha started to implement another part, but I don't know what is the current state.
Here is a description:
Before forwarding a mid-dialog request, a proxy would like to check that the dialog has been established using the proxy. To be able to do that, a piece information has to be inserted into INVITE message that can later help to identify the dialog. The only place in the SIP message where this can be done is Record-Route header field (because you can make sure that the the contents of the header field will be present in all subsequent requests).
The proxy will mark the dialog by inserting ftag parameter into it's Record-Route header field, the ftag parameter will contain From tag.
Later, when a mid-dialog request (for example BYE) comes, the proxy will do the following:
First it checks if From contains a domain the proxy is responsible for and if so, it will simply generate digest challenge and that's it. If the user is able to generate proper digest reply than he belongs to our domain and his requests will be forwarded.
If From doesn't contain a domain the proxy is responsible from then we can't use digest authentication--the sender wouldn't be able to generate proper reply.
In this case the proxy compares To tag with ftag parameter value from it's Route header field. If they are same then the dialog was established using the proxy and we are done -- we can relay the request.
The algorithm will also work with messages which do not establish a dialog like MESSAGE or OPTIONS because such message will have domain of our proxy either in From (we challenge) or in the Request-URI (processed automatically).
Current implementation status is that the ftag part has already been implemented and Juha recently sent a message that he is working on a function that can do the comparison with To tag.
The approach as described here won't prevent malicious users from using your proxy as a relay because they can forge the Route header field including ftag parameter, but it will prevent users that have "misconfigured" their user agents from using you as outbound proxy.
Great!
To prevent also malicious users, some kind of cryptographic protection of the Route header field would be needed.
This cryptographic protection is already implemented, but I have it in form of a patch and I haven't enough time yet to integrate and test it.
It should be relatively easy to do it - upon startup SER can generate some random string and then, when INVITE arrives, calculate one-way hash using this value and some other parameters that must persist during the dialog - e.g. Call-Id, From tag etc, then inserting it as a parameter into the Record-Route field. Then we can always check is the mid-dialog request should be serviced by us.
-Maxim
Maxim Sobolev writes:
If From doesn't contain a domain the proxy is responsible from then we can't use digest authentication--the sender wouldn't be able to generate proper reply.
In this case the proxy compares To tag with ftag parameter value from it's Route header field. If they are same then the dialog was established using the proxy and we are done -- we can relay the request.
the above is true if dialog was established by local user. in case the dialog was established by foreign user and that foreign user sends another, in-dialog request, then ftag will be equal to from tag.
so i implemented a function that checks if ftag is equal to either from or to tag, but didn't find it very useful after all. such test namely adds very little value to just checking if the request has to tag and dropping the ones that don't and are not send by or to a local user.
It should be relatively easy to do it - upon startup SER can generate some random string and then, when INVITE arrives, calculate one-way hash using this value and some other parameters that must persist during the dialog - e.g. Call-Id, From tag etc, then inserting it as a parameter into the Record-Route field. Then we can always check is the mid-dialog request should be serviced by us.
yes, i too have suggested that we do something like that. this kind of scheme, however, has no protection over faking new requests or replays if someone gets hold of one real request. also, if one gets hold of several real requests, then it would be possible to figure out what the key was unless the key changes often enough. so i have been wondering, if such mechanism is worth implementing.
-- juha
Juha Heinanen wrote:
Maxim Sobolev writes:
If From doesn't contain a domain the proxy is responsible from then we can't use digest authentication--the sender wouldn't be able to generate proper reply.
In this case the proxy compares To tag with ftag parameter value from it's Route header field. If they are same then the dialog was established using the proxy and we are done -- we can relay the request.
the above is true if dialog was established by local user. in case the dialog was established by foreign user and that foreign user sends another, in-dialog request, then ftag will be equal to from tag.
so i implemented a function that checks if ftag is equal to either from or to tag, but didn't find it very useful after all. such test namely adds very little value to just checking if the request has to tag and dropping the ones that don't and are not send by or to a local user.
It should be relatively easy to do it - upon startup SER can generate some random string and then, when INVITE arrives, calculate one-way hash using this value and some other parameters that must persist during the dialog - e.g. Call-Id, From tag etc, then inserting it as a parameter into the Record-Route field. Then we can always check is the mid-dialog request should be serviced by us.
yes, i too have suggested that we do something like that. this kind of scheme, however, has no protection over faking new requests or replays if someone gets hold of one real request.
Yes, that's true, but it IMHO is impossible to do something about that. In real world, however, it is very unlikely that a complete stranger will be able to get somehow real request, to do this he should be able to sniff communication channel between UA and proxy, in this case even digest-based auth mechanism would be pretty weak.
also, if one gets hold of several real requests, then it would be possible to figure out what the key was unless the key changes often enough. so i have been wondering, if such mechanism is worth implementing.
Not quite. If cryptographically-strong hashing function is used then it would be almost impossible to figure out server's portion of the key, even if attacker will be able to sniff channel during extended period of time.
-Maxim
-- juha
On 23-10 15:52, Maxim Sobolev wrote:
the above is true if dialog was established by local user. in case the dialog was established by foreign user and that foreign user sends another, in-dialog request, then ftag will be equal to from tag.
so i implemented a function that checks if ftag is equal to either from or to tag, but didn't find it very useful after all. such test namely adds very little value to just checking if the request has to tag and dropping the ones that don't and are not send by or to a local user.
It should be relatively easy to do it - upon startup SER can generate some random string and then, when INVITE arrives, calculate one-way
hash > using this value and some other parameters that must persist during the > dialog - e.g. Call-Id, From tag etc, then inserting it as a parameter > into the Record-Route field. Then we can always check is the mid-dialog > request should be serviced by us.
yes, i too have suggested that we do something like that. this kind of scheme, however, has no protection over faking new requests or replays if someone gets hold of one real request.
Yes, that's true, but it IMHO is impossible to do something about that. In real world, however, it is very unlikely that a complete stranger will be able to get somehow real request, to do this he should be able to sniff communication channel between UA and proxy, in this case even digest-based auth mechanism would be pretty weak.
also, if one gets hold of several real requests, then it would be possible to figure out what the key was unless the key changes often enough. so i have been wondering, if such mechanism is worth implementing.
Not quite. If cryptographically-strong hashing function is used then it would be almost impossible to figure out server's portion of the key, even if attacker will be able to sniff channel during extended period of time.
To prevent replay attacks, the hash would have to be calculated also over To tag. The hash should contain To tag because it is generated by remote party and thus the possible "attacker" can't predict it's value.
This also means we would have to update the Record-Route header field when processing 200 OK, which complicates things a bit.
If we don't add To tag, then it would be really easy to use same hash for other requests as well provided that you use the same From tag.
Another problem is that the hash can't have limited life-time because we don't know how long the session is going to take, so it will be possible to relay such messages forever.
However, there is another problem that comes on my mind -- how such Record-Route parameters would affect interoperability. Given the large amount of negative feedback I got because of lr=on and using r2 parameter mostly during Sip-its, I predict that including many (and quite long parameters) could cause interoperability problems.
Due to presence if strict routers in the wild, we can't make them header field parameter (i.e. parameters behind >), becuase strict routers will put the Route header field into Request-URI stripping of all header field parameters.
If we make them URI-parameters (i.e. before closing >), can we make sure that other implementations will be able to handle such Request-URI ? (Maybe I am too paranoid, but my experience is not very good).
I agree with Maxim that figuring out the secret key would be pretty hard.
Jan.
On 23-10 15:29, Jan Janak wrote:
To prevent replay attacks, the hash would have to be calculated also over To tag. The hash should contain To tag because it is generated by remote party and thus the possible "attacker" can't predict it's value.
This also means we would have to update the Record-Route header field when processing 200 OK, which complicates things a bit.
If we don't add To tag, then it would be really easy to use same hash for other requests as well provided that you use the same From tag.
I am silly, this is, of course, not going to work because callee would receive hash without to tag.
Jan.