diff --git a/src/modules/lost/functions.c b/src/modules/lost/functions.c index b7380dd2d68..3686402893f 100644 --- a/src/modules/lost/functions.c +++ b/src/modules/lost/functions.c @@ -84,6 +84,8 @@ int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url, str res = {NULL, 0}; str idhdr = {NULL, 0}; + int curlres = 0; + if(_con == NULL || _pidf == NULL || _url == NULL || _err == NULL) { LM_ERR("invalid parameter\n"); goto err; @@ -129,12 +131,9 @@ int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url, /* assemble locationRequest */ que.s = lost_held_location_request(did.s, &que.len); /* free memory */ - if(idhdr.s) { - pkg_free(idhdr.s); - idhdr.len = 0; - did.s = NULL; - did.len = 0; - } + lost_free_string(&idhdr); + did.s = NULL; + did.len = 0; if(!que.s) { LM_ERR("held request document error\n"); goto err; @@ -143,10 +142,19 @@ int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url, LM_DBG("held location request: \n[%s]\n", que.s); /* send locationRequest to location server - HTTP POST */ - httpapi.http_connect(_m, &con, NULL, &res, mtheld, &que); + curlres = httpapi.http_connect(_m, &con, NULL, &res, mtheld, &que); + /* only HTTP 2xx responses are accepted */ + if(curlres >= 300 || curlres < 100) { + LM_ERR("[%.*s] failed with error: %d\n", con.len, con.s, curlres); + res.s = NULL; + res.len = 0; + goto err; + } + + LM_DBG("[%.*s] returned: %d\n", con.len, con.s, curlres); + /* free memory */ - pkg_free(que.s); - que.len = 0; + lost_free_string(&que); /* read and parse the returned xml */ doc = xmlReadMemory(res.s, res.len, 0, NULL, XML_PARSE_RECOVER | XML_PARSE_NOBLANKS | XML_PARSE_NONET @@ -159,6 +167,7 @@ int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url, res.s); goto err; } + LM_DBG("xml document recovered\n"); } root = xmlDocGetRootElement(doc); @@ -225,6 +234,10 @@ int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url, err: if(doc) xmlFreeDoc(doc); + + lost_free_string(&idhdr); + lost_free_string(&que); + return LOST_CLIENT_ERROR; } @@ -255,13 +268,15 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, str con = {NULL, 0}; str ret = {NULL, 0}; str geo = {NULL, 0}; + str geohdr = {NULL, 0}; str name = {NULL, 0}; str pidf = {NULL, 0}; - str pidf_h = {NULL, 0}; + str pidfhdr = {NULL, 0}; - char *search = NULL; struct msg_start *fl; - + char *search = NULL; + int curlres = 0; + if(_con == NULL || _uri == NULL || _name == NULL || _err == NULL) { LM_ERR("invalid parameter\n"); goto err; @@ -310,13 +325,13 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, /* pidf from geolocation header */ if(pidf.len == 0) { LM_WARN("no pidf parameter, trying Geolocation header ...\n"); - geo.s = lost_get_geolocation_header(_m, &geo.len); - if(!geo.s) { + geohdr.s = lost_get_geolocation_header(_m, &geohdr.len); + if(!geohdr.s) { LM_ERR("geolocation header not found\n"); goto err; } else { /* pidf from multipart body, check cid scheme */ - search = geo.s; + search = geohdr.s; if((*(search + 0) == '<') && ((*(search + 1) == 'c') || (*(search + 1) == 'C')) && ((*(search + 2) == 'i') || (*(search + 2) == 'I')) @@ -343,25 +358,38 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, && ((*(search + 2) == 't') || (*(search + 2) == 'T')) && ((*(search + 3) == 'p') || (*(search + 3) == 'P')) && (*(search + 4) == ':')) { + geo.s = geohdr.s; + geo.len = geohdr.len; LM_DBG("url: \n[%.*s]\n", geo.len, geo.s); /* ! dereference pidf.lo at location server - HTTP GET */ /* ! requires hack in http_client module */ /* ! functions.c => http_client_query => query_params.oneline = 0; */ - httpapi.http_client_query(_m, geo.s, &pidf_h, NULL, NULL); - + curlres = httpapi.http_client_query(_m, geo.s, &pidfhdr, NULL, NULL); /* free memory */ - pkg_free(geo.s); + lost_free_string(&geohdr); + geo.s = NULL; geo.len = 0; + /* only HTTP 2xx responses are accepted */ + if(curlres >= 300 || curlres < 100) { + LM_ERR("http GET failed with error: %d\n", curlres); + pidfhdr.s = NULL; + pidfhdr.len = 0; + goto err; + } + + LM_DBG("http GET returned: %d\n", curlres); - if(!pidf_h.s) { + if(!pidfhdr.s) { LM_ERR("dereferencing location failed\n"); goto err; } - pidf.s = pidf_h.s; - pidf.len = pidf_h.len; + pidf.s = pidfhdr.s; + pidf.len = pidfhdr.len; } + /* free memory */ + lost_free_string(&geohdr); } } @@ -399,6 +427,10 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, || (!xmlStrcmp(root->name, (const xmlChar *)"locationResponse"))) { /* get the geolocation: point or circle, urn, ... */ loc = lost_new_loc(urn); + if(!loc) { + LM_ERR("location object allocation failed\n"); + goto err; + } if(lost_parse_location_info(root, loc) < 0) { LM_ERR("location element not found\n"); goto err; @@ -411,12 +443,9 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, } /* free memory */ - if(pidf_h.s) { - pkg_free(pidf_h.s); - pidf_h.len = 0; - pidf.s = NULL; - pidf.len = 0; - } + lost_free_string(&pidfhdr); + pidf.s = NULL; + pidf.len = 0; /* check if connection exits */ if(httpapi.http_connection_exists(&con) == 0) { @@ -426,8 +455,12 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, /* assemble findService request */ res.s = lost_find_service_request(loc, &res.len); /* free memory */ - lost_free_loc(loc); + if(loc) { + lost_free_loc(loc); + loc = NULL; + } xmlFreeDoc(doc); + doc = NULL; if(!res.s) { LM_ERR("lost request failed\n"); @@ -437,9 +470,20 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, LM_DBG("findService request: \n[%.*s]\n", res.len, res.s); /* send findService request to mapping server - HTTP POST */ - httpapi.http_connect(_m, &con, NULL, &ret, mtlost, &res); - pkg_free(res.s); - res.len = 0; + curlres = httpapi.http_connect(_m, &con, NULL, &ret, mtlost, &res); + /* only HTTP 2xx responses are accepted */ + if(curlres >= 300 || curlres < 100) { + LM_ERR("[%.*s] failed with error: %d\n", con.len, con.s, curlres); + ret.s = NULL; + ret.len = 0; + goto err; + } + + LM_DBG("[%.*s] returned: %d\n", con.len, con.s, curlres); + + /* free memory */ + lost_free_string(&res); + if(!ret.s) { LM_ERR("findService request failed\n"); goto err; @@ -502,12 +546,10 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, /* free memory */ xmlFreeDoc(doc); - if(ret.s) { - pkg_free(ret.s); - ret.len = 0; - } + doc = NULL; + lost_free_string(&ret); - /* set writeable pvars */ + /* set writable pvars */ pvname.rs = name; pvname.rs.s = name.s; pvname.rs.len = name.len; @@ -539,13 +581,10 @@ int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name, lost_free_loc(loc); if(doc) xmlFreeDoc(doc); - if(pidf_h.s) { - pkg_free(pidf_h.s); - pidf_h.len = 0; - } - if(ret.s) { - pkg_free(ret.s); - ret.len = 0; - } + + lost_free_string(&pidfhdr); + lost_free_string(&geohdr); + lost_free_string(&ret); + return LOST_CLIENT_ERROR; } diff --git a/src/modules/lost/lost.c b/src/modules/lost/lost.c index c4b5e663c9b..5bdba54eb2e 100644 --- a/src/modules/lost/lost.c +++ b/src/modules/lost/lost.c @@ -124,10 +124,6 @@ static int mod_init(void) /* Child initialization function */ static int child_init(int rank) { - if(rank == PROC_INIT || rank == PROC_MAIN || rank == PROC_TCP_MAIN) { - return 0; /* do nothing for the main process */ - } - return 0; } @@ -152,7 +148,7 @@ static int fixup_lost_held_query(void **param, int param_no) return -1; } if(((pv_spec_t *)(*param))->setf == NULL) { - LM_ERR("result pvar is not writeble\n"); + LM_ERR("result pvar is not writable\n"); return -1; } return 0; @@ -195,7 +191,7 @@ static int fixup_lost_held_query_id(void **param, int param_no) return -1; } if(((pv_spec_t *)(*param))->setf == NULL) { - LM_ERR("result pvar is not writeble\n"); + LM_ERR("result pvar is not writable\n"); return -1; } return 0; @@ -237,7 +233,7 @@ static int fixup_lost_query(void **param, int param_no) return -1; } if(((pv_spec_t *)(*param))->setf == NULL) { - LM_ERR("result pvar is not writeble\n"); + LM_ERR("result pvar is not writable\n"); return -1; } return 0; @@ -279,7 +275,7 @@ static int fixup_lost_query_all(void **param, int param_no) return -1; } if(((pv_spec_t *)(*param))->setf == NULL) { - LM_ERR("result pvar is not writeble\n"); + LM_ERR("result pvar is not writable\n"); return -1; } return 0; diff --git a/src/modules/lost/pidf.c b/src/modules/lost/pidf.c index e41858342b2..c018313bdc0 100755 --- a/src/modules/lost/pidf.c +++ b/src/modules/lost/pidf.c @@ -21,9 +21,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * History: - * -------- - * 2007-04-14 initial version (anca) */ /*! \file @@ -101,12 +98,9 @@ xmlNodePtr xmlNodeGetNodeByName( while(cur) { xmlNodePtr match = NULL; if(xmlStrcasecmp(cur->name, (unsigned char *)name) == 0) { - if(!ns - || (cur->ns - && xmlStrcasecmp( - cur->ns->prefix, (unsigned char *)ns) - == 0)) - return cur; + if(!ns || (cur->ns && + xmlStrcasecmp(cur->ns->prefix, (unsigned char *)ns) == 0)) + return cur; } match = xmlNodeGetNodeByName(cur->children, name, ns); if(match) diff --git a/src/modules/lost/pidf.h b/src/modules/lost/pidf.h index e2f62fd6fa9..78c5d84dcf6 100755 --- a/src/modules/lost/pidf.h +++ b/src/modules/lost/pidf.h @@ -21,15 +21,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * History: - * -------- - * 2006-08-15 initial version (anca) */ /*! \file * \brief Kamailio Presence_XML :: PIDF handling * \ref pidf.c - * \ingroup presence_xml + * \ingroup lost */ diff --git a/src/modules/lost/utilities.c b/src/modules/lost/utilities.c index 2df10753b0c..78fb45caab5 100644 --- a/src/modules/lost/utilities.c +++ b/src/modules/lost/utilities.c @@ -106,29 +106,40 @@ void lost_free_loc(p_loc_t ptr) pkg_free(ptr); } +void lost_free_string(str *string) +{ + str ptr = *string; + + if(ptr.s) { + pkg_free(ptr.s); + ptr.s = NULL; + ptr.len = 0; + } +} + /* * lost_new_loc(urn) * creates a new location object in private memory and returns a pointer */ p_loc_t lost_new_loc(str rurn) { - s_loc_t *ptr; - char *id; - char *urn; + s_loc_t *ptr = NULL;; + char *id = NULL; + char *urn = NULL; ptr = (s_loc_t *)pkg_malloc(sizeof(s_loc_t)); if(ptr == NULL) { - LM_ERR("no more private memory\n"); + goto err; } id = (char *)pkg_malloc(RANDSTRSIZE * sizeof(char) + 1); if(id == NULL) { - LM_ERR("no more private memory\n"); + goto err; } urn = (char *)pkg_malloc(rurn.len + 1); if(urn == NULL) { - LM_ERR("no more private memory\n"); + goto err; } memset(urn, 0, rurn.len + 1); @@ -145,6 +156,10 @@ p_loc_t lost_new_loc(str rurn) ptr->recursive = 0; return ptr; + +err: + LM_ERR("no more private memory\n"); + return NULL; } /* @@ -156,7 +171,6 @@ char *lost_get_content(xmlNodePtr node, const char *name, int *lgth) xmlNodePtr cur = node; char *content; char *cnt = NULL; - int len; *lgth = 0; @@ -166,6 +180,7 @@ char *lost_get_content(xmlNodePtr node, const char *name, int *lgth) cnt = (char *)pkg_malloc((len + 1) * sizeof(char)); if(cnt == NULL) { LM_ERR("No more private memory\n"); + return cnt; } memset(cnt, 0, len + 1); @@ -188,7 +203,6 @@ char *lost_get_property(xmlNodePtr node, const char *name, int *lgth) xmlNodePtr cur = node; char *content; char *cnt = NULL; - int len; *lgth = 0; @@ -198,6 +212,7 @@ char *lost_get_property(xmlNodePtr node, const char *name, int *lgth) cnt = (char *)pkg_malloc((len + 1) * sizeof(char)); if(cnt == NULL) { LM_ERR("No more private memory\n"); + return cnt; } memset(cnt, 0, len + 1); @@ -220,21 +235,19 @@ char *lost_get_childname(xmlNodePtr node, const char *name, int *lgth) xmlNodePtr cur = node; xmlNodePtr parent = NULL; xmlNodePtr child = NULL; - char *cnt = NULL; int len; *lgth = 0; - parent = xmlNodeGetNodeByName(cur, name, NULL); child = parent->children; if(child) { len = strlen((char *)child->name); - cnt = (char *)pkg_malloc((len + 1) * sizeof(char)); if(cnt == NULL) { LM_ERR("no more private memory\n"); + return cnt; } memset(cnt, 0, len + 1); @@ -271,6 +284,7 @@ char *lost_get_geolocation_header(struct sip_msg *msg, int *lgth) res = (char *)pkg_malloc((hf->body.len + 1) * sizeof(char)); if(res == NULL) { LM_ERR("no more private memory\n"); + return res; } else { memset(res, 0, hf->body.len + 1); memcpy(res, hf->body.s, hf->body.len + 1); @@ -311,6 +325,7 @@ char *lost_get_pai_header(struct sip_msg *msg, int *lgth) res = (char *)pkg_malloc((hf->body.len + 1) * sizeof(char)); if(res == NULL) { LM_ERR("no more private memory\n"); + return res; } else { memset(res, 0, hf->body.len + 1); @@ -351,6 +366,7 @@ char *lost_get_from_header(struct sip_msg *msg, int *lgth) res = (char *)pkg_malloc((f_body->uri.len + 1) * sizeof(char)); if(res == NULL) { LM_ERR("no more private memory\n"); + return res; } else { memset(res, 0, f_body->uri.len + 1); memcpy(res, f_body->uri.s, f_body->uri.len + 1); @@ -361,7 +377,6 @@ char *lost_get_from_header(struct sip_msg *msg, int *lgth) return res; } - /* * lost_parse_location_info(node, loc) * parses locationResponse and writes results to location object @@ -442,8 +457,16 @@ char *lost_held_location_request(char *id, int *lgth) /* create request */ request = xmlNewDoc(BAD_CAST "1.0"); + if(!request) { + LM_ERR("locationRequest xmlNewDoc() failed\n"); + return doc; + } /* locationRequest - element */ ptrLocationRequest = xmlNewNode(NULL, BAD_CAST "locationRequest"); + if(!ptrLocationRequest) { + LM_ERR("locationRequest xmlNewNode() failed\n"); + return doc; + } xmlDocSetRootElement(request, ptrLocationRequest); /* properties */ xmlNewProp(ptrLocationRequest, BAD_CAST "xmlns", @@ -456,6 +479,10 @@ char *lost_held_location_request(char *id, int *lgth) xmlNewProp(ptrLocationType, BAD_CAST "exact", BAD_CAST "false"); /* device - element */ ptrDevice = xmlNewChild(ptrLocationRequest, NULL, BAD_CAST "device", NULL); + if(!ptrDevice) { + LM_ERR("locationRequest xmlNewChild() failed\n"); + return doc; + } /* properties */ xmlNewProp(ptrDevice, BAD_CAST "xmlns", BAD_CAST "urn:ietf:params:xml:ns:geopriv:held:id"); @@ -464,10 +491,15 @@ char *lost_held_location_request(char *id, int *lgth) xmlNewChild(ptrDevice, NULL, BAD_CAST "uri", BAD_CAST buf); xmlDocDumpFormatMemory(request, &xmlbuff, &buffersize, 0); + if(!xmlbuff) { + LM_ERR("locationRequest xmlDocDumpFormatMemory() failed\n"); + return doc; + } doc = (char *)pkg_malloc((buffersize + 1) * sizeof(char)); if(doc == NULL) { LM_ERR("no more private memory\n"); + return doc; } memset(doc, 0, buffersize + 1); @@ -524,8 +556,16 @@ char *lost_find_service_request(p_loc_t loc, int *lgth) */ /* create request */ request = xmlNewDoc(BAD_CAST "1.0"); + if(!request) { + LM_ERR("findService request xmlNewDoc() failed\n"); + return doc; + } /* findService - element */ ptrFindService = xmlNewNode(NULL, BAD_CAST "findService"); + if(!ptrFindService) { + LM_ERR("findService xmlNewNode() failed\n"); + return doc; + } xmlDocSetRootElement(request, ptrFindService); /* set properties */ xmlNewProp(ptrFindService, BAD_CAST "xmlns", @@ -544,6 +584,10 @@ char *lost_find_service_request(p_loc_t loc, int *lgth) /* Point */ if(loc->radius == 0) { ptrPoint = xmlNewChild(ptrLocation, NULL, BAD_CAST "Point", NULL); + if(!ptrPoint) { + LM_ERR("locationRequest xmlNewChild() failed\n"); + return doc; + } xmlNewProp(ptrPoint, BAD_CAST "xmlns", BAD_CAST "http://www.opengis.net/gml"); xmlNewProp(ptrPoint, BAD_CAST "srsName", @@ -553,6 +597,10 @@ char *lost_find_service_request(p_loc_t loc, int *lgth) } else { /* circle - Point */ ptrCircle = xmlNewChild(ptrLocation, NULL, BAD_CAST "gs:Circle", NULL); + if(!ptrCircle) { + LM_ERR("locationRequest xmlNewChild() failed\n"); + return doc; + } xmlNewProp(ptrCircle, BAD_CAST "xmlns:gml", BAD_CAST "http://www.opengis.net/gml"); xmlNewProp(ptrCircle, BAD_CAST "xmlns:gs", @@ -565,6 +613,10 @@ char *lost_find_service_request(p_loc_t loc, int *lgth) snprintf(buf, BUFSIZE, "%d", loc->radius); ptrRadius = xmlNewChild( ptrCircle, NULL, BAD_CAST "gs:radius", BAD_CAST buf); + if(!ptrRadius) { + LM_ERR("locationRequest xmlNewChild() failed\n"); + return doc; + } xmlNewProp(ptrRadius, BAD_CAST "uom", BAD_CAST "urn:ogc:def:uom:EPSG::9001"); } @@ -573,10 +625,15 @@ char *lost_find_service_request(p_loc_t loc, int *lgth) xmlNewChild(ptrFindService, NULL, BAD_CAST "service", BAD_CAST buf); xmlDocDumpFormatMemory(request, &xmlbuff, &buffersize, 0); + if(!xmlbuff) { + LM_ERR("findService request xmlDocDumpFormatMemory() failed\n"); + return doc; + } doc = (char *)pkg_malloc((buffersize + 1) * sizeof(char)); if(doc == NULL) { LM_ERR("no more private memory\n"); + return doc; } memset(doc, 0, buffersize + 1); diff --git a/src/modules/lost/utilities.h b/src/modules/lost/utilities.h index f6bf9351360..68722148b21 100644 --- a/src/modules/lost/utilities.h +++ b/src/modules/lost/utilities.h @@ -40,6 +40,8 @@ #define BUFSIZE 128 /* temporary buffer to hold geolocation */ #define RANDSTRSIZE 16 /* temporary id in a findService request */ +#define LOSTFREE(x) pkg_free(x); x = NULL; + typedef struct { char *identity; @@ -54,6 +56,7 @@ typedef struct void lost_rand_str(char *, size_t); void lost_free_loc(p_loc_t); +void lost_free_string(str *); int lost_get_location_object(p_loc_t, xmlDocPtr, xmlNodePtr); int lost_parse_location_info(xmlNodePtr node, p_loc_t loc);