Hello,
Please find attached a patch to add oma user-profile and pres-content
(avatar) support to the xcap_server module.
To make use of these changes I also had to update my kamailio.cfg (based
on the example from
http://kb.asipto.com/kamailio:presence:k31-made-simple). In particular
I had to update the event_route[xhttp:request] clause so that:
* the xcap-caps response includes the auids and namespace entries
for user-profile and pres-content
* modify the auth user checking because (unlike the XML documents
that were already there) any user can retrieve user-profile and
pres-content, but only the owner can update them.
For reference, my updated event_route[xhttp:request] clause is included
below.
Regards,
Peter
event_route[xhttp:request] {
#!ifdef WITH_PRESENCE
xdbg("===== xhttp: request [$rv] $rm => $hu\n");
#!ifdef WITH_XHTTPAUTH
if (!www_authorize("xcap", "subscriber")) {
www_challenge("xcap", "0");
exit;
}
#!endif
if($hu=~"^/xcap-root/") {
set_reply_close();
set_reply_no_connect();
# xcap ops
$xcapuri(u=>data) = $hu;
if($xcapuri(u=>xuid)=~"^sip:.+@.+")
$var(uri) = $xcapuri(u=>xuid);
else if($xcapuri(u=>xuid)=~".+@.+")
$var(uri) = "sip:" + $xcapuri(u=>xuid);
else
$var(uri) = "sip:"+ $xcapuri(u=>xuid) + "@" + $Ri;
if($xcapuri(u=>auid)=="xcap-caps") {
$var(xbody) =
"<?xml version='1.0' encoding='UTF-8'?>
<xcap-caps xmlns='urn:ietf:params:xml:ns:xcap-caps'>
<auids>
<auid>rls-services</auid>
<auid>pidf-manipulation</auid>
<auid>xcap-caps</auid>
<auid>resource-lists</auid>
<auid>pres-rules</auid>
<auid>org.openmobilealliance.pres-rules</auid>
<auid>org.openmobilealliance.user-profile</auid>
<auid>org.openmobilealliance.pres-conent</auid>
</auids>
<extensions>
</extensions>
<namespaces>
<namespace>urn:ietf:params:xml:ns:rls-services</namespace>
<namespace>urn:ietf:params:xml:ns:pidf</namespace>
<namespace>urn:ietf:params:xml:ns:xcap-caps</namespace>
<namespace>urn:ietf:params:xml:ns:resource-lists</namespace>
<namespace>urn:ietf:params:xml:ns:pres-rules</namespace>
<namespace>urn:oma:xml:xdm:user-profile</namespace>
<namespace>urn:oma:xml:prs:pres-content</namespace>
</namespaces>
</xcap-caps>";
xhttp_reply("200", "ok", "application/xcap-caps+xml",
"$var(xbody)");
exit;
}
switch($rm) {
case "PUT":
#!ifdef WITH_XHTTPAUTH
# be sure only auth user updates its documents
if ($au!=$(var(uri){uri.user})) {
xhttp_reply("403", "Forbidden", "text/html",
"<html><body>$si:$sp</body></html>");
exit;
}
#!endif
xcaps_put("$var(uri)", "$hu", "$rb");
if($xcapuri(u=>auid)=~"pres-rules") {
pres_update_watchers("$var(uri)", "presence");
pres_refresh_watchers("$var(uri)", "presence", 1);
}
exit;
break;
case "GET":
#!ifdef WITH_XHTTPAUTH
if (!($xcapuri(u=>auid)=~"user-profile" || $xcapuri(u=>auid)=~"pres-content")) {
# be sure only auth user gets non-profile documents
if ($au!=$(var(uri){uri.user})) {
xhttp_reply("403", "Forbidden", "text/html",
"<html><body>$si:$sp</body></html>");
exit;
}
}
#!endif
xcaps_get("$var(uri)", "$hu");
exit;
break;
case "DELETE":
#!ifdef WITH_XHTTPAUTH
# be sure only auth user deletes its documents
if ($au!=$(var(uri){uri.user})) {
xhttp_reply("403", "Forbidden", "text/html",
"<html><body>$si:$sp</body></html>");
exit;
}
#!endif
xcaps_del("$var(uri)", "$hu");
if($xcapuri(u=>auid)=~"pres-rules") {
pres_update_watchers("$var(uri)", "presence");
pres_refresh_watchers("$var(uri)", "presence", 1);
}
exit;
break;
}
}
# http ops
xhttp_reply("200", "ok", "text/html", "<html><body>OK: $si:$sp</body></html>");
exit;
#!endif
}
--
Peter Dunkley
Technical Director
Crocodile RCS Ltd
Module: sip-router
Branch: master
Commit: f5f934fa55a7938cb85b85e7661d5a9dcc5629c6
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f5f934f…
Author: Marius Bucur <marius.bucur(a)1and1.ro>
Committer: Marius Bucur <marius.bucur(a)1and1.ro>
Date: Wed May 11 13:43:08 2011 +0300
modules/carrieroute: fixed a bug in carrieroute
the bug caused carrieroute to crash when an invalid SIP message is received (e.g. with no callid)
---
modules/carrierroute/cr_func.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/carrierroute/cr_func.c b/modules/carrierroute/cr_func.c
index 714a130..1006228 100644
--- a/modules/carrierroute/cr_func.c
+++ b/modules/carrierroute/cr_func.c
@@ -437,7 +437,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
}
break;
case alg_crc32_nofallback:
- if ((prob = (hash_func(msg, hash_source, rf->max_targets) + 1)) < 0) {
+ if ((prob = (hash_func(msg, hash_source, rf->max_targets))) < 0) {
LM_ERR("could not hash message with CRC32");
return -1;
}
@@ -445,7 +445,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
* this function just tries only a backup rule and otherwise
* returns -1. This way we get an error
*/
- if ((rr = get_rule_by_hash(rf, prob)) == NULL) {
+ if ((rr = get_rule_by_hash(rf, prob + 1)) == NULL) {
LM_CRIT("no route found\n");
return -1;
}
Module: sip-router
Branch: 3.1
Commit: ea8430ddb32e2f45f29362a97ffed2fee011f6a3
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ea8430d…
Author: Marius Bucur <marius.bucur(a)1and1.ro>
Committer: Marius Bucur <marius.bucur(a)1and1.ro>
Date: Wed May 11 13:43:08 2011 +0300
modules/carrieroute: fixed a bug in carrieroute
the bug caused carrieroute to crash when an invalid SIP message is received (e.g. with no callid)
---
modules/carrierroute/cr_func.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/carrierroute/cr_func.c b/modules/carrierroute/cr_func.c
index 714a130..1006228 100644
--- a/modules/carrierroute/cr_func.c
+++ b/modules/carrierroute/cr_func.c
@@ -437,7 +437,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
}
break;
case alg_crc32_nofallback:
- if ((prob = (hash_func(msg, hash_source, rf->max_targets) + 1)) < 0) {
+ if ((prob = (hash_func(msg, hash_source, rf->max_targets))) < 0) {
LM_ERR("could not hash message with CRC32");
return -1;
}
@@ -445,7 +445,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
* this function just tries only a backup rule and otherwise
* returns -1. This way we get an error
*/
- if ((rr = get_rule_by_hash(rf, prob)) == NULL) {
+ if ((rr = get_rule_by_hash(rf, prob + 1)) == NULL) {
LM_CRIT("no route found\n");
return -1;
}
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
The following task has a new comment added:
FS#129 - Segfault parsing STUN body
User who did this - Francesco Castellano (fcastellano)
----------
Hi Andrei,
even if I cannot put the patches directly on our production system; I finally succeeded to reproduce the crash through a handycrafted STUN packet. After the patches being added no new crash happened (and correct STUN dialogs continue to work). In attachment the packet I used for the tests (sending it to the sip-router STUN server via "nc -v -q 2 -u SIP_PROXY_HOST SIP_PROXY_PORT < stun.pkt").
Best regards,
Francesco Castellano
----------
One or more files have been attached.
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=129#comment213
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
The following task has a new comment added:
FS#129 - Segfault parsing STUN body
User who did this - Francesco Castellano (fcastellano)
----------
Hi Andrei,
even if I cannot put the patches directly on our production system; I finally succeeded to reproduce the crash through a handycrafted STUN packet. After the patches being added no new crash happened (and correct STUN dialogs continue to work). In attachment the packet I used for the tests (sending it to the sip-router STUN server via "nc -v -q 2 -u SIP_PROXY_HOST SIP_PROXY_PORT < stun.pkt").
Best regards,
Francesco Castellano
----------
One or more files have been attached.
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=129#comment212
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
Module: sip-router
Branch: carstenbock/ims
Commit: a80729125de45d2e147a970315c08df378626f64
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a807291…
Author: Carsten Bock <carsten(a)bock.info>
Committer: Carsten Bock <carsten(a)bock.info>
Date: Mon May 9 13:55:16 2011 +0200
- extended the API of Record-Route in order to retrieve the routeset and the remote URI (needed for later validation/enforcement of route-sets in requests)
---
modules_k/rr/api.c | 3 +
modules_k/rr/api.h | 10 ++++
modules_k/rr/loose.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++-
modules_k/rr/loose.h | 19 ++++++++
4 files changed, 151 insertions(+), 1 deletions(-)
diff --git a/modules_k/rr/api.c b/modules_k/rr/api.c
index 55af538..0835b72 100644
--- a/modules_k/rr/api.c
+++ b/modules_k/rr/api.c
@@ -64,6 +64,9 @@ int load_rr( struct rr_binds *rrb )
rrb->get_route_param = get_route_param;
rrb->register_rrcb = register_rrcb;
rrb->append_fromtag = append_fromtag;
+ rrb->get_remoteuri = get_remoteuri;
+ rrb->get_routeset = get_routeset;
+ rrb->rr_type = rr_type;
return 1;
}
diff --git a/modules_k/rr/api.h b/modules_k/rr/api.h
index 09c9a4e..91da2ea 100644
--- a/modules_k/rr/api.h
+++ b/modules_k/rr/api.h
@@ -46,12 +46,19 @@
#include "loose.h"
#include "rr_cb.h"
+#define RR_TYPE_STRICT_LOOSE (1<<1)
+#define RR_TYPE_STRICT_STRICT (1<<2)
+#define RR_TYPE_LOOSE_LOOSE (1<<3)
+#define RR_TYPE_LOOSE_STRICT (1<<4)
+
typedef int (*add_rr_param_t)(struct sip_msg*, str*);
typedef int (*check_route_param_t)(struct sip_msg*, regex_t*);
typedef int (*is_direction_t)(struct sip_msg*, int);
typedef int (*get_route_param_t)(struct sip_msg*, str*, str*);
typedef int (*record_route_f)(struct sip_msg*, str*);
typedef int (*loose_route_f)(struct sip_msg*);
+typedef str* (*get_remoteuri_t)(struct sip_msg*);
+typedef str* (*get_routeset_t)(struct sip_msg*, int *nr_routes);
/*! record-route API export binding */
typedef struct rr_binds {
@@ -63,6 +70,9 @@ typedef struct rr_binds {
get_route_param_t get_route_param;
register_rrcb_t register_rrcb;
int append_fromtag;
+ get_remoteuri_t get_remoteuri;
+ get_routeset_t get_routeset;
+ int rr_type;
} rr_api_t;
typedef int (*load_rr_f)( struct rr_binds* );
diff --git a/modules_k/rr/loose.c b/modules_k/rr/loose.c
index 9cf1ef9..5d0fccf 100644
--- a/modules_k/rr/loose.c
+++ b/modules_k/rr/loose.c
@@ -43,6 +43,7 @@
#include "loose.h"
#include "rr_cb.h"
#include "rr_mod.h"
+#include "api.h"
#define RR_ERROR -1 /*!< An error occured while processing route set */
@@ -639,6 +640,8 @@ static inline int after_strict(struct sip_msg* _m)
if (is_strict(&puri.params)) {
LM_DBG("Next hop: '%.*s' is strict router\n", uri.len, ZSW(uri.s));
+ rr_type = RR_TYPE_STRICT_STRICT;
+
/* Previous hop was a strict router and the next hop is strict
* router too. There is no need to save R-URI again because it
* is saved already. In fact, in this case we will behave exactly
@@ -671,6 +674,7 @@ static inline int after_strict(struct sip_msg* _m)
} else {
LM_DBG("Next hop: '%.*s' is loose router\n",
uri.len, ZSW(uri.s));
+ rr_type = RR_TYPE_STRICT_LOOSE;
if(get_maddr_uri(&uri, &puri)!=0) {
LM_ERR("failed to check maddr\n");
@@ -800,6 +804,9 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
if (res > 0) { /* No next route found */
LM_DBG("No next URI found\n");
status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
+
+ rr_type = RR_TYPE_LOOSE_LOOSE;
+
goto done;
}
rt = (rr_t*)hdr->parsed;
@@ -835,6 +842,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
if (res > 0) { /* No next route found */
LM_DBG("no next URI found\n");
status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
+ rr_type = RR_TYPE_LOOSE_LOOSE;
goto done;
}
rt = (rr_t*)hdr->parsed;
@@ -858,6 +866,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s));
if (is_strict(&puri.params)) {
LM_DBG("Next URI is a strict router\n");
+ rr_type = RR_TYPE_LOOSE_STRICT;
if (handle_sr(_m, hdr, rt) < 0) {
LM_ERR("failed to handle strict router\n");
return RR_ERROR;
@@ -865,7 +874,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
} else {
/* Next hop is loose router */
LM_DBG("Next URI is a loose router\n");
-
+ rr_type = RR_TYPE_LOOSE_LOOSE;
if(get_maddr_uri(&uri, &puri)!=0) {
LM_ERR("checking maddr failed\n");
return RR_ERROR;
@@ -905,6 +914,7 @@ done:
int loose_route(struct sip_msg* _m)
{
int ret;
+ rr_type = 0;
if (find_first_route(_m) != 0) {
LM_DBG("There is no Route HF\n");
@@ -1133,3 +1143,111 @@ upstream:
last_dir = RR_FLOW_UPSTREAM;
return (dir==RR_FLOW_UPSTREAM)?0:-1;
}
+
+/*!
+ * \brief Gets the URI of the remote destination, based on the route-set.
+ *
+ * \param msg - request that will have the Route header parameter searched
+ * \return A str with the URI of the remote target.
+ */
+str* get_remoteuri(struct sip_msg *msg) {
+ int res;
+ struct hdr_field *hdr;
+ rr_t *rt,*prev;
+ str *uri;
+
+ if (msg == NULL) {
+ LM_ERR("No SIP-Message, internal error?!?!\n");
+ return NULL;
+ }
+ /* If we are a loose-router,
+ we find the Remote URI in the Request URI. */
+ if ((rr_type == RR_TYPE_LOOSE_LOOSE)
+ || (rr_type == RR_TYPE_LOOSE_STRICT)) {
+ return &msg->first_line.u.request.uri;
+ } else if (rr_type == RR_TYPE_STRICT_LOOSE) {
+ /* We are a strict router, so the loose_route() sets the
+ new URI from the previous strict routing. */
+ return &msg->new_uri;
+ } else if (rr_type == RR_TYPE_STRICT_STRICT) {
+ res = find_rem_target(msg, &hdr, &rt, &prev);
+ if (res < 0) {
+ /* Failed to find the last route-target */
+ LM_ERR("Failed to find the last route-target\n");
+ return NULL;
+ } else if (res > 0) {
+ /* No remote target found */
+ LM_ERR("No remote target found!\n");
+ return NULL;
+ }
+ uri = &rt->nameaddr.uri;
+ if(get_maddr_uri(uri, 0)!=0) {
+ LM_ERR("failed to check maddr\n");
+ return 0;
+ }
+ return uri;
+ } else {
+ LM_ERR("Unknown / invalid routing type %d\n", rr_type);
+ return 0;
+ }
+}
+
+/*!
+ * \brief Returns a list of the URI's from the route-headers
+ *
+ * \param msg - request that will have the Route header parameter searched
+ * \return An array of str with the URI of the next hops.
+ */
+#define MAX_HDRS 32
+str* get_routeset(struct sip_msg *msg,int *nr_routes) {
+ /* The destination, where the URI's are stored */
+ static str uris[MAX_HDRS];
+ /* Iterator for all record-route headers */
+ struct hdr_field *hdr;
+ /* The parsed route-header structure */
+ rr_t * rr;
+
+ if (msg == NULL || msg->route == NULL) {
+ LM_ERR("No SIP-Message or no route-headers!\n");
+ return NULL;
+ }
+
+ if (!nr_routes) {
+ LM_ERR("nr_routes parameter is invalid!\n");
+ return NULL;
+ }
+ *nr_routes = 0;
+
+ if ((rr_type == RR_TYPE_STRICT_STRICT)
+ || (rr_type == RR_TYPE_LOOSE_STRICT)) {
+ /* must manually insert RURI, as it was part
+ * of the route deleted to make up for strict routing */
+ uris[(*nr_routes)++] = msg->new_uri;
+ }
+
+ hdr = msg->route;
+ while (hdr != NULL) {
+ if (parse_rr(hdr) < 0) {
+ LM_ERR("Invalid Route-Header, failed to parse\n");
+ return NULL;
+ }
+ /* Get the parsed content of the route-header */
+ rr = (rr_t*)hdr->parsed;
+ while (rr) {
+ uris[(*nr_routes)++] = rr->nameaddr.uri;
+ if(*nr_routes==MAX_HDRS) {
+ LM_ERR("Too many route-headers!!!\n");
+ return 0;
+ }
+ rr = rr->next;
+ }
+ hdr = hdr->next;
+ }
+
+
+ /* if SS - remove last route */
+ if (rr_type == RR_TYPE_STRICT_STRICT)
+ (*nr_routes)--;
+
+ return uris;
+}
diff --git a/modules_k/rr/loose.h b/modules_k/rr/loose.h
index 6b1bdc9..31157d1 100644
--- a/modules_k/rr/loose.h
+++ b/modules_k/rr/loose.h
@@ -38,6 +38,10 @@
#define RR_FLOW_DOWNSTREAM (1<<0)
#define RR_FLOW_UPSTREAM (1<<1)
+/*!
+ * \brief Next-Hop is a strict or loose-router?
+ */
+int rr_type;
/*!
* \brief Do loose routing as per RFC3261
@@ -92,5 +96,20 @@ int is_direction(struct sip_msg *msg, int dir);
*/
int get_route_param( struct sip_msg *msg, str *name, str *val);
+/*!
+ * \brief Gets the URI of the remote destination, based on the route-set.
+ *
+ * \param msg - request that will have the Route header parameter searched
+ * \return A str with the URI of the remote target.
+ */
+str* get_remoteuri(struct sip_msg *msg);
+
+/*!
+ * \brief Returns a list of the URI's from the route-headers
+ *
+ * \param msg - request that will have the Route header parameter searched
+ * \return An array of str with the URI of the next hops.
+ */
+str* get_routeset(struct sip_msg *msg, int *nr_routes);
#endif /* LOOSE_H */