Hoola!
Viendo distintos documentos por ahí, veo que cada uno pone un poco a su manera la detección del loose route.
De todos los que he visto, el que más me ha gustado ha sido el del libro "Building Telephony Systems with OpenSER", en el que se propone lo siguiente:
if (has_totag()) { if (loose_route()) { if (message == "INVITE") route(x); if (message == "REFER") route(y); .... } else { sl_rend_reply(403, "Fuck you!") }
La pregunta es: se supone que esta (primero mirar el totag y luego loose_route) es la manera "más correcta" de comprobar que lo que viene esta in-dialog?
Y ya que estoy, otra preguntilla :) Qué mensajes in-dialog han de ir autenticados? (INVITE y REFER fijo, pero los demás?). Puntero a RFC vale como respuesta :)
Thnx!!
El Sunday 25 May 2008 20:26:41 Saúl Ibarra escribió:
Hoola!
Viendo distintos documentos por ahí, veo que cada uno pone un poco a su manera la detección del loose route.
De todos los que he visto, el que más me ha gustado ha sido el del libro "Building Telephony Systems with OpenSER", en el que se propone lo siguiente:
if (has_totag()) { if (loose_route()) { if (message == "INVITE") route(x); if (message == "REFER") route(y); .... } else { sl_rend_reply(403, "Fuck you!") }
Ojo con eso que tal y como está permites mensajes initial-request (has_totag() = FALSE) pero que contengan "Route", o sea, que sería como un open relay.
Yo hago esto:
---------------- # ¿in-dialog? if (loose_route()) $var(loose_route) = 1; else $var(loose_route) = 0;
### In-dialog procesing:
if (has_totag() && $var(loose_route)) { if (message == "INVITE") route(x); if (message == "REFER") route(y); ... }
### Initial request processing:
if (!has_totag() && $var(loose_route)) { # Initial request -> preloaded ROUTE set? if ($var(loose_route)) { xlog("L_ERROR", "ERROR: Attempt to route with preloaded Route\n"); sl_send_reply("403","Preload Route denied"); } } } ---------------------
Es importante guardar y usar la variable $var(loose_route) ya que no podemos llamar dos veces a la función "loose_route()" puesto que haría algo impredecible.
De todas formas, creo que mi forma es un tanto rebuscada.
La pregunta es: se supone que esta (primero mirar el totag y luego loose_route) es la manera "más correcta" de comprobar que lo que viene esta in-dialog?
Que está in-dialog sólo viene determinado por la presencia del "tag" en el "To", nada más. Se supone que como OpenSer le ha añadido previamente a responses de ese diálogo el "Record-Route" entonces los siguientes mensajes en dialog tendrá un "Route", y de hecho es dificil que llegue un mensaje in-dialog sin "Route" (pero no imposible ni mucho menos). Pero la clave de que un mensaje sea in-dialog es únicamente la presencia de "tag" en el "To".
Y ya que estoy, otra preguntilla :) Qué mensajes in-dialog han de ir autenticados? (INVITE y REFER fijo, pero los demás?).
Esta pregunta la hice yo en su día en esta misma lista, recuerdo que había buenas conclusiones. Por cierto, el re-INVITE **NO** se debe autenticar necesariamente (de hecho no hay razón alguna para hacerlo), y el REFER puede hacerse o no. Más seguro es que sí, pero ojo si el llamado es un alias y luego exiges "check_from()" en la autenticación a un REFER desde dicho alias.
Saludos.
2008/5/26 Iñaki Baz Castillo ibc@in.ilimit.es:
El Sunday 25 May 2008 20:26:41 Saúl Ibarra escribió:
Hoola!
Viendo distintos documentos por ahí, veo que cada uno pone un poco a su manera la detección del loose route.
De todos los que he visto, el que más me ha gustado ha sido el del libro "Building Telephony Systems with OpenSER", en el que se propone lo siguiente:
if (has_totag()) { if (loose_route()) { if (message == "INVITE") route(x); if (message == "REFER") route(y); .... } else { sl_rend_reply(403, "Fuck you!") }
Ojo con eso que tal y como está permites mensajes initial-request (has_totag() = FALSE) pero que contengan "Route", o sea, que sería como un open relay.
Yo hago esto:
# ¿in-dialog? if (loose_route()) $var(loose_route) = 1; else $var(loose_route) = 0;
### In-dialog procesing:
if (has_totag() && $var(loose_route)) { if (message == "INVITE") route(x); if (message == "REFER") route(y); ... }
### Initial request processing:
if (!has_totag() && $var(loose_route)) { # Initial request -> preloaded ROUTE set? if ($var(loose_route)) { xlog("L_ERROR", "ERROR: Attempt to route with preloaded Route\n"); sl_send_reply("403","Preload Route denied"); } } }
hasta aquí OK, pero esta segunda parte me pierde un poco: ni NO tiene totag, el if haría if (1 && $var(loose_route)) entonces, la única menra de entrar en ese if no sería que loose_route valiera 1? No podríoa ser algo así?:
### Initial request processing:
if (!has_totag()) { # Initial request -> preloaded ROUTE set? if ($var(loose_route)) { xlog("L_ERROR", "ERROR: Attempt to route with preloaded Route\n"); sl_send_reply("403","Preload Route denied"); } }
if (method=="INVITE") route(x); if (method == "REGISTER") route(z); }
Es importante guardar y usar la variable $var(loose_route) ya que no podemos llamar dos veces a la función "loose_route()" puesto que haría algo impredecible.
De todas formas, creo que mi forma es un tanto rebuscada.
Lo cierto es que le encuentro sentido :)
La pregunta es: se supone que esta (primero mirar el totag y luego loose_route) es la manera "más correcta" de comprobar que lo que viene esta in-dialog?
Que está in-dialog sólo viene determinado por la presencia del "tag" en el "To", nada más. Se supone que como OpenSer le ha añadido previamente a responses de ese diálogo el "Record-Route" entonces los siguientes mensajes en dialog tendrá un "Route", y de hecho es dificil que llegue un mensaje in-dialog sin "Route" (pero no imposible ni mucho menos). Pero la clave de que un mensaje sea in-dialog es únicamente la presencia de "tag" en el "To".
ACK.
Y ya que estoy, otra preguntilla :) Qué mensajes in-dialog han de ir autenticados? (INVITE y REFER fijo, pero los demás?).
Esta pregunta la hice yo en su día en esta misma lista, recuerdo que había buenas conclusiones. Por cierto, el re-INVITE **NO** se debe autenticar necesariamente (de hecho no hay razón alguna para hacerlo), y el REFER puede hacerse o no. Más seguro es que sí, pero ojo si el llamado es un alias y luego exiges "check_from()" en la autenticación a un REFER desde dicho alias.
Umm, entonces puede que si pido autenticación para los re-INVITE y REFER algún UA me de por el culo?!
Saludos.
Salu2 y graciaxx!!
El Monday 26 May 2008 16:01:23 Saúl Ibarra escribió:
# ¿in-dialog? if (loose_route()) $var(loose_route) = 1; else $var(loose_route) = 0;
Cierto es que estaba mal puesto el comentario de: # ¿in-dialog?
Pero bueno, aquí hemos guardado en una variable si existía o no una cabecera "Route" además de que al ejecutar "loose_route()" OpenSer ya ha quitado la primera "Route" si apuntaba a sí mismo y esas cosas.
### In-dialog procesing:
if (has_totag() && $var(loose_route)) { if (message == "INVITE") route(x); if (message == "REFER") route(y); ... }
Aquí hemos procesado el caso de que fuese in-dialog (hast_totag()) y además tuviese el correspondiente "Route" (si no sería un in-dialog incorrecto).
### Initial request processing:
if (!has_totag() && $var(loose_route)) { # Initial request -> preloaded ROUTE set? if ($var(loose_route)) {
Efectivamente esta línea sobra, fallo mío al copiar (tenía dos versiones y las junté mal). Sobra este último "if".
xlog("L_ERROR", "ERROR: Attempt to route with preloaded
Route\n"); sl_send_reply("403","Preload Route denied"); } } }
Aquí hemos comprobado que era un "initial-request" y que entonces no tenía un "Route" (si lo tiene sería peligroso pues podría constituir un intento de relay).
hasta aquí OK, pero esta segunda parte me pierde un poco: ni NO tiene totag, el if haría if (1 && $var(loose_route)) entonces, la única menra de entrar en ese if no sería que loose_route valiera 1? No podríoa ser algo así?:
Sí, fallo tonto mío al pegar.
Y ya que estoy, otra preguntilla :) Qué mensajes in-dialog han de ir autenticados? (INVITE y REFER fijo, pero los demás?).
Esta pregunta la hice yo en su día en esta misma lista, recuerdo que había buenas conclusiones. Por cierto, el re-INVITE **NO** se debe autenticar necesariamente (de hecho no hay razón alguna para hacerlo), y el REFER puede hacerse o no. Más seguro es que sí, pero ojo si el llamado es un alias y luego exiges "check_from()" en la autenticación a un REFER desde dicho alias.
Umm, entonces puede que si pido autenticación para los re-INVITE y REFER algún UA me de por el culo?!
Sólo si tienes alias. Ejemplo:
- "A" llama a "AliasB"
- "AliasB" resulta ser un alias de B por lo que OpenSer ruta la llamada a la localización de B, pero en el From y To pone:
From: A To: AliasB
- B responde y tal.
- Al de un rato B envía un REFER. Depende del UAC es posible que mantenga el From y To (pero invertidos), o sea:
REFER A From: AliasB To: A
- OpenSer pide autenticación a B quien genera un nuevo REFER:
REFER A From: AliasB To: A Proxy-Authenticacion: Digest username="B" <--- OJO !!
- Si OpenSer ejecuta "check_from()" le dará FALSE puesto que el username del From ("AliasB") es distinto que el username de autenticación ("B").
Lo que no tengo claro es si en el REFER B tendría que poner como "From" el "To" que recibió en el INVITE ("AliasB") o poner "B". Twinkle toma la primera opción por lo que fallaría el REFER. Otros tfnos no lo sé.
Saludos.
sr-users-es@lists.kamailio.org