1 /**
2  * Functions to force or check the service-routes
3  *
4  * Copyright (c) 2013 Carsten Bock, ng-voice GmbH
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 #include "service_routes.h"
24 #include "ims_registrar_pcscf_mod.h"
25 #include "save.h"
26 #include "../../core/parser/parse_via.h"
27 #include "../../core/parser/msg_parser.h"
28 #include "../../core/data_lump.h"
29 #include "../../lib/ims/ims_getters.h"
30 
31 #define STR_APPEND(dst,src)\
32         {memcpy((dst).s+(dst).len,(src).s,(src).len);\
33         (dst).len = (dst).len + (src).len;}
34 
35 // ID of current message
36 static unsigned int current_msg_id = 0;
37 // Pointer to current contact_t
38 static pcontact_t * c = NULL;
39 
40 extern usrloc_api_t ul;
41 extern int ignore_contact_rxport_check;
42 static str * asserted_identity;
43 static str * registration_contact;
44 
45 /*!
46  * \brief Parse the message and find first occurrence of Route header field.
47  * \param _m SIP message
48  * \return -1 or -2 on a parser error, 0 if there is a Route HF and 1 if there is no Route HF
49  */
find_first_route(struct sip_msg * _m)50 static inline int find_first_route(struct sip_msg* _m)
51 {
52 	if (parse_headers(_m, HDR_ROUTE_F, 0) == -1) {
53 		LM_ERR("failed to parse headers\n");
54 		return -1;
55 	} else {
56 		if (_m->route) {
57 			if (parse_rr(_m->route) < 0) {
58 				LM_ERR("failed to parse Route HF\n");
59 				return -2;
60 			}
61 			return 0;
62 		} else {
63 			LM_DBG("No Route headers found\n");
64 			return 1;
65 		}
66 	}
67 }
68 
69 /*!
70  * \brief Find and parse next Route header field
71  * \param _m SIP message
72  * \param _hdr SIP header
73  * \return negative on failure, 0 if the Route header was already parsed, 1 if no next
74  * Route header could be found
75  */
find_next_route(struct sip_msg * _m,struct hdr_field ** _hdr)76 static inline int find_next_route(struct sip_msg* _m, struct hdr_field** _hdr)
77 {
78 	struct hdr_field* ptr;
79 
80 	ptr = (*_hdr)->next;
81 
82 	/* Try to find already parsed Route headers */
83 	while(ptr) {
84 		if (ptr->type == HDR_ROUTE_T) goto found;
85 		ptr = ptr->next;
86 	}
87 
88 	/* There are no already parsed Route headers, try to find next
89 	 * occurrence of Route header
90 	 */
91 	if (parse_headers(_m, HDR_ROUTE_F, 1) == -1) {
92 		LM_ERR("failed to parse headers\n");
93 		return -1;
94 	}
95 
96 	if ((_m->last_header->type!=HDR_ROUTE_T) || (_m->last_header==*_hdr)) {
97 		LM_DBG("No next Route HF found\n");
98 		return 1;
99 	}
100 
101 	ptr = _m->last_header;
102 
103  found:
104 	if (parse_rr(ptr) < 0) {
105 		LM_ERR("failed to parse Route body\n");
106 		return -2;
107 	}
108 
109 	*_hdr = ptr;
110 	return 0;
111 }
112 
checkcontact(struct sip_msg * _m,pcontact_t * c)113 int checkcontact(struct sip_msg* _m, pcontact_t * c) {
114 	int security_server_port = -1;
115 	str received_host = {0, 0};
116 	char srcip[50];
117 
118 	LM_DBG("Port %d (search %d), Proto %d (search %d), reg_state %s (search %s)\n",
119 		c->received_port, _m->rcv.src_port, c->received_proto, _m->rcv.proto,
120 		reg_state_to_string(c->reg_state), reg_state_to_string(PCONTACT_REGISTERED)
121 	);
122 
123 	if (c->security) {
124 		switch (c->security->type) {
125 		case SECURITY_IPSEC:
126 			security_server_port = c->security->data.ipsec->port_uc;
127 			break;
128 		case SECURITY_TLS:
129 		case SECURITY_NONE:
130 			break;
131 		}
132 	} else if (c->security_temp) {
133 		switch (c->security_temp->type) {
134 		case SECURITY_IPSEC:
135 			security_server_port = c->security_temp->data.ipsec->port_uc;
136 			break;
137 		case SECURITY_TLS:
138 		case SECURITY_NONE:
139 			break;
140 		}
141 	}
142 
143 	if ((ignore_reg_state || (c->reg_state == PCONTACT_REGISTERED))
144                 && (ignore_contact_rxport_check || (c->received_port == _m->rcv.src_port) || (security_server_port == _m->rcv.src_port))
145                 && (ignore_contact_rxport_check||(c->received_proto == _m->rcv.proto))) {
146 
147 		received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
148 		received_host.s = srcip;
149 		LM_DBG("Received host len %d (search %d)\n", c->received_host.len, received_host.len);
150 		// Then check the length:
151 		if (c->received_host.len == received_host.len) {
152 			LM_DBG("Received host %.*s (search %.*s)\n",
153 				c->received_host.len, c->received_host.s,
154 				received_host.len, received_host.s);
155 
156 			// Finally really compare the "received_host"
157 			if (!memcmp(c->received_host.s, received_host.s, received_host.len)) {
158                             LM_DBG("check contact passed\n");
159 				return 0;
160 		}
161 	}
162 	}
163         LM_DBG("check contact failed\n");
164 	return 1;
165 }
166 
167 /**
168  * get PContact-Structure for message
169  * (search only once per Request)
170  */
171 
getContactP(struct sip_msg * _m,udomain_t * _d,enum pcontact_reg_states reg_state,char service_routes[][MAXROUTESIZE],int num_service_routes)172 pcontact_t * getContactP(struct sip_msg* _m, udomain_t* _d, enum pcontact_reg_states reg_state, char service_routes[][MAXROUTESIZE], int num_service_routes) {
173 	ppublic_t * p;
174 	contact_body_t *b = 0;
175 	contact_t *ct;
176 	pcontact_info_t search_ci;
177 	str received_host = {0, 0};
178 	char srcip[50];
179 	struct via_body *vb;
180 	unsigned short port, proto;
181 	str host;
182 	sip_uri_t contact_uri;
183 	int mustRetryViaSearch = 0;
184 	int mustRetryReceivedSearch = 0;
185 
186 	LM_DBG("number of service routes to look for is %d\n", num_service_routes);
187     b = cscf_parse_contacts(_m);
188 
189     if (_m->first_line.type == SIP_REPLY && _m->contact && _m->contact->parsed && b->contacts) {
190 		mustRetryViaSearch = 1;
191 		mustRetryReceivedSearch = 1;
192         LM_DBG("This is a reply - to look for contact we favour the contact header above the via (b2bua)... if no contact we will use last via\n");
193         ct = b->contacts;
194         host = ct->uri;
195         if (parse_uri(ct->uri.s, ct->uri.len, &contact_uri) != 0) {
196             LM_WARN("Failed to parse contact [%.*s]\n", ct->uri.len, ct->uri.s);
197             return NULL;
198         }
199         host = contact_uri.host;
200         port = contact_uri.port_no ? contact_uri.port_no : 5060;
201         proto = contact_uri.proto;
202         if (proto == 0) {
203             LM_DBG("Contact protocol not specified - using received\n");
204             proto = _m->rcv.proto;
205         }
206     } else {
207         if (_m->first_line.type == SIP_REPLY)
208             LM_DBG("This is a reply but we are forced to use the via header\n");
209         else
210             LM_DBG("This is a request - using first via to find contact\n");
211 
212         vb = cscf_get_ue_via(_m);
213         host = vb->host;
214         port = vb->port ? vb->port : 5060;
215         proto = vb->proto;
216     }
217 
218     LM_DBG("searching for contact with host:port:proto contact [%d://%.*s:%d]\n", proto, host.len, host.s, port);
219 
220     received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof (srcip));
221     received_host.s = srcip;
222 
223 //    if (_m->id != current_msg_id) {
224         current_msg_id = _m->id;
225         c = NULL;
226 	//search_ci.reg_state = PCONTACT_REGISTERED;          //we can do this because this function is always called expecting a REGISTERED contact
227 	memset(&search_ci, 0, sizeof(struct pcontact_info));
228     search_ci.reg_state = reg_state;
229 	search_ci.received_host.s = received_host.s;
230 	search_ci.received_host.len = received_host.len;
231 	search_ci.received_port = _m->rcv.src_port;
232 	search_ci.received_proto = _m->rcv.proto;
233 	search_ci.searchflag = SEARCH_RECEIVED;
234 	search_ci.num_service_routes = 0;
235 	if (is_registered_fallback2ip == 1) {
236 		search_ci.searchflag = SEARCH_NORMAL;
237 	}
238 	search_ci.via_host = host;
239 	search_ci.via_port = port;
240 	search_ci.via_prot = proto;
241 	search_ci.aor.s = 0;
242 	search_ci.aor.len = 0;
243 
244 	int size = num_service_routes==0?1:num_service_routes;
245 	str s_service_routes[size];
246 	int i;
247 	for (i=0;i<num_service_routes;i++) {
248 		s_service_routes[i].s = service_routes[i];
249 		s_service_routes[i].len = strlen(service_routes[i]);
250 		LM_DBG("Setting service routes str for pos %d to %.*s", i, s_service_routes[i].len, s_service_routes[i].s);
251 	}
252 	if (num_service_routes > 0) {
253 		LM_DBG("asked to search for specific service routes...\n");
254 		search_ci.service_routes = s_service_routes;
255 		search_ci.num_service_routes = num_service_routes;
256 		search_ci.extra_search_criteria = SEARCH_SERVICE_ROUTES;
257 	}
258 
259 //	b = cscf_parse_contacts(_m);
260 tryagain:
261 	if (b && b->contacts) {
262 		for (ct = b->contacts; ct; ct = ct->next) {
263 			search_ci.aor = ct->uri;
264 			if (ul.get_pcontact(_d, &search_ci, &c) == 0) {
265 				if (checkcontact(_m, c) != 0) {
266 					c = NULL;
267 				} else {
268 					break;
269 				}
270 			}
271 		}
272 	} else {
273 		LM_WARN("No contact-header found...\n");
274 	}
275 
276 	if ((c == NULL) && (is_registered_fallback2ip == 1)) {
277 		LM_INFO("Contact not found based on Contact-header, trying IP/Port/Proto\n");
278 		//			received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
279 		//			received_host.s = srcip;
280 		search_ci.searchflag = SEARCH_RECEIVED;
281 		if (ul.get_pcontact(_d, &search_ci, &c) == 1) {
282 			LM_DBG("No entry in usrloc for %.*s:%i (Proto %i) found!\n", received_host.len, received_host.s, _m->rcv.src_port, _m->rcv.proto);
283 		} else {
284 			if (checkcontact(_m, c) != 0) {
285 				c = NULL;
286 			}
287 		}
288 	}
289 
290 	if ((c == NULL) && (is_registered_fallback2ip == 2)) {
291 		LM_INFO("Contact not found based on IP/Port/Proto, trying Contact-header\n");
292 		search_ci.searchflag = SEARCH_NORMAL;
293 		if (ul.get_pcontact(_d, &search_ci, &c) == 1) {
294 		} else {
295 			if (checkcontact(_m, c) != 0) {
296 				c = NULL;
297 			}
298 		}
299 	}
300 
301 	asserted_identity = NULL;
302 	registration_contact = NULL;
303 	if (c) {
304                 LM_DBG("Trying to set asserted identity field");
305 		registration_contact = &c->contact_user;
306 		p = c->head;
307 		while (p) {
308                         LM_DBG("Checking through contact users");
309 			if (p->is_default == 1) {
310                             LM_DBG("Found default contact user so setting asserted identity");
311                             asserted_identity = &p->public_identity;
312                         }
313 			p = p->next;
314 		}
315 	}
316         if (asserted_identity != NULL && asserted_identity->len > 0) {
317             LM_DBG("Have set the asserted_identity param to [%.*s]\n", asserted_identity->len, asserted_identity->s);
318         } else {
319             LM_DBG("Asserted identity not set");
320         }
321 
322 
323 //    LM_DBG("pcontact flag is [%d]\n", c->flags);
324 //    if (c && (c->flags & (1<<FLAG_READFROMDB)) != 0) {
325 //        LM_DBG("we have a contact that was read fresh from the DB....\n");
326 //    }
327 	if (!c && mustRetryViaSearch) {
328 		LM_DBG("This is a reply so we will search using the last via once more...\n");
329 		vb = cscf_get_ue_via(_m);
330 		search_ci.via_host = vb->host;
331 		search_ci.via_port = vb->port ? vb->port : 5060;
332 		search_ci.via_prot = vb->proto;
333 		mustRetryViaSearch = 0;
334 		goto tryagain;
335 	}
336 
337 	if (!c && mustRetryReceivedSearch) {
338 		LM_DBG("This is a reply and we still don't have a match - will try src ip/port of message\n");
339 		search_ci.via_host = received_host;
340 		search_ci.via_port = _m->rcv.src_port;
341 		search_ci.via_prot = _m->rcv.proto;
342 		mustRetryReceivedSearch = 0;
343 		goto tryagain;
344 	}
345 
346     return c;
347 }
348 
349 /**
350  * Check, if a user-agent follows the indicated service-routes
351  */
check_service_routes(struct sip_msg * _m,udomain_t * _d)352 int check_service_routes(struct sip_msg* _m, udomain_t* _d) {
353 	struct sip_uri uri;
354 	int i;
355 	struct hdr_field *hdr;
356 	rr_t *r;
357 	char routes[MAXROUTES][MAXROUTESIZE];
358 	unsigned int num_routes = 0;
359 
360 	struct via_body * vb;
361 	unsigned short port;
362 	unsigned short proto;
363 	/* Contact not found => not following service-routes */
364 //	if (c == NULL) return -1;
365 
366 	/* Search for the first Route-Header: */
367 	if (find_first_route(_m) < 0) return -1;
368 
369 //	LM_DBG("Got %i Route-Headers.\n", c->num_service_routes);
370 
371 	vb = cscf_get_ue_via(_m);
372 	port = vb->port?vb->port:5060;
373 	proto = vb->proto;
374 
375 	/* Lock this record while working with the data: */
376 	ul.lock_udomain(_d, &vb->host, port, proto);
377 
378 	if (_m->route) {
379 		hdr = _m->route;
380 		r = (rr_t*)hdr->parsed;
381 		//get rid of ourselves from route header
382 		if (r) {
383 			LM_DBG("Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s);
384 			while (r && (parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri) == 0)
385 			  && check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) {
386 				LM_DBG("Self\n");
387 				/* Check for more headers and fail, if it was the last one
388 				   Check, if service-routes are indicated.
389 				   If yes, request is not following service-routes */
390 				if (find_next_route(_m, &hdr) != 0)
391 					r = NULL;
392 				else
393 					r = (rr_t*)hdr->parsed;
394 
395 				LM_DBG("hdr is %p\n", hdr);
396 				LM_DBG("r is %p\n", r);
397 				if (r)
398 					LM_DBG("Next Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s);
399 			}
400 
401 			int i = 0;
402 			while (r) {
403 				memset(routes[i],0,MAXROUTESIZE);
404 				memcpy(routes[i], r->nameaddr.uri.s, r->nameaddr.uri.len);
405 
406 				if (find_next_route(_m, &hdr) != 0)
407 					r = NULL;
408 				else
409 					r = (rr_t*)hdr->parsed;
410 
411 				i += 1;
412 				num_routes += 1;
413 			}
414 
415 			LM_DBG("num_routes is %d\n", num_routes);
416 			if (num_routes == 0) {
417 				LM_DBG("Request doesn't have any route headers (except those pointing here), to check service-route...ignoring\n");
418 				goto error;
419 			}
420 			for (i=0; i<num_routes; i++) {
421 				LM_DBG("route %d for checking is %s\n", i, routes[i]);
422 			}
423 			pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED, routes, num_routes);
424 			if (!c) {
425 				LM_DBG("no contact found in usrloc when checking for service route\n");
426 				goto error;
427 			}
428 
429 			LM_DBG("we have a contact which satisifes the routes...\n");
430 			ul.unlock_udomain(_d, &vb->host, port, proto);
431 			return 1;
432 		}
433 	} else {
434 		LM_DBG("Request doesn't have any route headers to check service-route...ignoring\n");
435 		goto error;
436 	}
437 
438 	pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED, 0, 0);
439 	if (!c) {
440 		LM_DBG("no contact found in usrloc when checking for service route\n");
441 		goto error;
442 	}
443 
444 	/* Check the route-set: */
445 	if (_m->route) {
446 		hdr = _m->route;
447 		LM_DBG("hdr is %p\n", hdr);
448 		/* Check, if the first host is ourself: */
449 		r = (rr_t*)hdr->parsed;
450 		if (r) {
451 			LM_DBG("Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s);
452 			/* Skip first headers containing myself: */
453 			while (r && (parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri) == 0)
454 			  && check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) {
455 				LM_DBG("Self\n");
456 				/* Check for more headers and fail, if it was the last one
457 				   Check, if service-routes are indicated.
458 				   If yes, request is not following service-routes */
459 				if (find_next_route(_m, &hdr) != 0) r = NULL;
460 				else r = (rr_t*)hdr->parsed;
461 
462 				if (!r && (c->num_service_routes > 0)) {
463 					LM_DBG("Not enough route-headers in Message\n");
464 					goto error;
465 				}
466 				LM_DBG("hdr is %p\n", hdr);
467 				LM_DBG("r is %p\n", r);
468 				if (r)
469 					LM_DBG("Next Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s);
470 			}
471 			LM_DBG("We have %d service-routes\n", c->num_service_routes);
472 			/* Then check the following headers: */
473 			for (i=0; i< c->num_service_routes; i++) {
474 				LM_DBG("Route must be: %.*s\n", c->service_routes[i].len, c->service_routes[i].s);
475 
476 				/* No more Route-Headers? Not following service-routes */
477 				if (!r) {
478 					LM_DBG("No more route headers in message.\n");
479 					 goto error;
480 				}
481 
482 				LM_DBG("Route is: %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s);
483 
484 				/* Check length: */
485 				if (r->nameaddr.uri.len != c->service_routes[i].len) {
486 					LM_DBG("Length does not match.\n");
487 					 goto error;
488 				}
489 				/* Check contents: */
490 				if (strncasecmp(r->nameaddr.uri.s, c->service_routes[i].s, c->service_routes[i].len) != 0) {
491 					LM_DBG("String comparison failed.\n");
492 					 goto error;
493 				}
494 				if (find_next_route(_m, &hdr) != 0) r = NULL;
495 				else r = (rr_t*)hdr->parsed;
496 			}
497 
498 			/* Check, if it was the last route-header in the message: */
499 			if (r) {
500 				LM_DBG("Too many route headers in message.\n");
501 				 goto error;
502 			}
503 		} else {
504 			LM_WARN("Strange: Route-Header is present, but not parsed?!?");
505 			if (c->num_service_routes > 0) goto error;
506 		}
507 	} else {
508 		LM_DBG("No route header in Message.\n");
509 		/* No route-header? Check, if service-routes are indicated.
510 		   If yes, request is not following service-routes */
511 		if (c->num_service_routes > 0) goto error;
512 	}
513 	/* Unlock domain */
514 	ul.unlock_udomain(_d, &vb->host, port, proto);
515 	return 1;
516 error:
517 	/* Unlock domain */
518 	ul.unlock_udomain(_d, &vb->host, port, proto);
519 	return -1;
520 }
521 
522 static str route_start={"Route: <",8};
523 static str route_sep={">, <",4};
524 static str route_end={">\r\n",3};
525 
526 /**
527  * Force Service routes (upon request)
528  */
force_service_routes(struct sip_msg * _m,udomain_t * _d)529 int force_service_routes(struct sip_msg* _m, udomain_t* _d) {
530 	struct hdr_field *it;
531 	int i;
532 	str new_route_header;
533 	struct lump* lmp = NULL;
534 	char * buf;
535 	pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED,0 ,0);
536 //	char srcip[20];
537 //	str received_host;
538         struct via_body* vb;
539         unsigned short port;
540         unsigned short proto;
541 
542 	// Contact not found => not following service-routes
543 	if (c == NULL) return -1;
544 
545 	/* we need to be sure we have seen all HFs */
546 	parse_headers(_m, HDR_EOH_F, 0);
547 
548         vb = cscf_get_ue_via(_m);
549         port = vb->port?vb->port:5060;
550         proto = vb->proto;
551 
552 	/* Save current buffer */
553 	buf = _m->buf;
554 
555 	// Delete old Route headers:
556 	if (_m->route) {
557 		for (it = _m->route; it; it = it->next) {
558 			if (it->type == HDR_ROUTE_T) {
559 				if ((lmp = del_lump(_m, it->name.s - buf, it->len, HDR_ROUTE_T)) == 0) {
560 					LM_ERR("del_lump failed \n");
561 					return -1;
562 				}
563 			}
564 		}
565 	}
566 
567 	/* Reset dst_uri if previously set either by loose route or manually */
568 	if (_m->dst_uri.s && _m->dst_uri.len) {
569 		pkg_free(_m->dst_uri.s);
570 		_m->dst_uri.s = NULL;
571 		_m->dst_uri.len = 0;
572 	}
573 
574 //	received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
575 //	received_host.s = srcip;
576 
577 	/* Lock this record while working with the data: */
578 	ul.lock_udomain(_d, &vb->host, port, proto);
579 
580 	if (c->num_service_routes > 0) {
581 		/* Create anchor for new Route-Header: */
582 		lmp = anchor_lump(_m, _m->headers->name.s - buf,0,0);
583 		if (lmp == 0) {
584 			LM_ERR("Failed to get anchor lump\n");
585 			goto error;
586 		}
587 		/* Calculate the length: */
588 		new_route_header.len = route_start.len +
589 			route_end.len + (c->num_service_routes-1) * route_sep.len;
590 
591 		for(i=0; i< c->num_service_routes; i++)
592 			new_route_header.len+=c->service_routes[i].len;
593 		/* Allocate the memory for this new header: */
594 		new_route_header.s = pkg_malloc(new_route_header.len);
595 		if (!new_route_header.s) {
596 			LM_ERR("Error allocating %d bytes\n", new_route_header.len);
597 			goto error;
598 		}
599 
600 		/* Construct new header */
601 		new_route_header.len = 0;
602 		STR_APPEND(new_route_header, route_start);
603 		for(i=0; i < c->num_service_routes; i++) {
604 			if (i) STR_APPEND(new_route_header, route_sep);
605 			STR_APPEND(new_route_header, c->service_routes[i]);
606 		}
607 		STR_APPEND(new_route_header, route_end);
608 
609 		LM_DBG("Setting route header to <%.*s> \n", new_route_header.len, new_route_header.s);
610 
611 		if ((lmp = insert_new_lump_after(lmp, new_route_header.s, new_route_header.len, HDR_ROUTE_T)) == 0) {
612 			LM_ERR("Error inserting new route set\n");
613 			pkg_free(new_route_header.s);
614 			goto error;
615 		}
616 
617 		LM_DBG("Setting dst_uri to <%.*s> \n", c->service_routes[0].len,
618 			c->service_routes[0].s);
619 
620 		if (set_dst_uri(_m, &c->service_routes[0]) !=0 ) {
621 			LM_ERR("Error setting new dst uri\n");
622 			goto error;
623 		}
624 	}
625 	/* Unlock domain */
626 	ul.unlock_udomain(_d, &vb->host, port, proto);
627 	return 1;
628 error:
629 	/* Unlock domain */
630 	ul.unlock_udomain(_d, &vb->host, port, proto);
631 	return -1;
632 
633     return 1;
634 }
635 
636 /**
637  * Check, if source is registered.
638  */
is_registered(struct sip_msg * _m,udomain_t * _d)639 int is_registered(struct sip_msg* _m, udomain_t* _d) {
640 	if (getContactP(_m, _d, PCONTACT_REGISTERED, 0 ,0) != NULL) return 1;
641 	return -1;
642 }
643 
644 /**
645  * Get the current asserted identity for the user
646  */
get_asserted_identity(struct sip_msg * _m)647 str * get_asserted_identity(struct sip_msg* _m) {
648 	if (_m->id != current_msg_id) {
649 		LM_ERR("Unable to get asserted identity: Please call is_registered first!\n");
650 		return NULL;
651 	} else return asserted_identity;
652 }
653 
654 
655 /**
656  * Get the contact used during registration of this user
657  */
get_registration_contact(struct sip_msg * _m)658 str * get_registration_contact(struct sip_msg* _m) {
659 	if (_m->id != current_msg_id) {
660 		LM_ERR("Unable to get contact used during registration: Please call is_registered first!\n");
661 		return NULL;
662 	} else return registration_contact;
663 }
664 
665 
666 /**
667  * checked if passed identity is an asserted identity
668  */
assert_identity(struct sip_msg * _m,udomain_t * _d,str identity)669 int assert_identity(struct sip_msg* _m, udomain_t* _d, str identity) {
670 	// Public identities of this contact
671 	struct ppublic * p;
672 	//remove <> braces if there are
673 	if(identity.s[0]=='<' && identity.s[identity.len-1]=='>') {
674 		identity.s++;
675 		identity.len -= 2;
676 	}
677 	LM_DBG("Identity to assert: %.*s\n", identity.len, identity.s);
678 
679 	if (getContactP(_m, _d, PCONTACT_REGISTERED|PCONTACT_REG_PENDING_AAR|PCONTACT_REG_PENDING, 0, 0) != NULL) {
680 		for (p = c->head; p; p = p->next) {
681 			LM_DBG("Public identity: %.*s\n", p->public_identity.len, p->public_identity.s);
682 			    /* Check length: */
683 			    if (identity.len == p->public_identity.len) {
684 				    /* Check contents: */
685 				    if (strncasecmp(identity.s, p->public_identity.s, identity.len) == 0) {
686 					    LM_DBG("Match!\n");
687 					    return 1;
688 				    }
689 			    } else LM_DBG("Length does not match.\n");
690 			}
691 		}
692 	LM_INFO("Contact not found based on Contact, trying IP/Port/Proto\n");
693 	str received_host = {0, 0};
694 	char srcip[50];
695 
696 	received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip));
697 	received_host.s = srcip;
698 	if (ul.assert_identity(_d, &received_host, _m->rcv.src_port, _m->rcv.proto, &identity) == 0)
699 		return -1;
700 	else
701 		return 1;
702 }
703 
704 
705 /**
706  * Add proper asserted identities based on registration
707  */
708 
709 static str p_asserted_identity_s={"P-Asserted-Identity: ",21};
710 static str p_asserted_identity_m={"<",1};
711 static str p_asserted_identity_e={">\r\n",3};
712 
assert_called_identity(struct sip_msg * _m,udomain_t * _d)713 int assert_called_identity(struct sip_msg* _m, udomain_t* _d) {
714 
715 	int ret=CSCF_RETURN_FALSE;
716 	str called_party_id={0,0},x={0,0};
717 	struct sip_msg* req;
718 	struct hdr_field *h=0;
719 
720 	//get request from reply
721 	req = get_request_from_reply(_m);
722 	if (!req) {
723 		LM_ERR("Unable to get request from reply for REGISTER. No transaction\n");
724 		goto error;
725 	}
726 
727 	called_party_id = cscf_get_public_identity_from_called_party_id(req, &h);
728 
729 
730 	if (!called_party_id.len){
731 		goto error;
732 	}else{
733 		LM_DBG("Called Party ID from request: %.*s\n", called_party_id.len, called_party_id.s);
734 		x.len = p_asserted_identity_s.len+p_asserted_identity_m.len+called_party_id.len+p_asserted_identity_e.len;
735 		x.s = pkg_malloc(x.len);
736 		if (!x.s){
737 			LM_ERR("P_assert_called_identity: Error allocating %d bytes\n",	x.len);
738 			x.len=0;
739 			goto error;
740 		}
741 		x.len=0;
742 		STR_APPEND(x,p_asserted_identity_s);
743 		STR_APPEND(x,p_asserted_identity_m);
744 		STR_APPEND(x,called_party_id);
745 		STR_APPEND(x,p_asserted_identity_e);
746 
747 		if (cscf_add_header(_m,&x,HDR_OTHER_T))
748 			ret = CSCF_RETURN_TRUE;
749 		else
750 		    goto error;
751 	}
752 
753 	return ret;
754 
755 error:
756 	ret=CSCF_RETURN_FALSE;
757 	return ret;
758 }
759 
pcscf_unregister(udomain_t * _d,str * uri,str * received_host,int received_port)760 int pcscf_unregister(udomain_t* _d, str * uri, str * received_host, int received_port) {
761 	int result = -1;
762 	struct pcontact * pcontact;
763 	struct pcontact_info ci;
764     	memset(&ci, 0, sizeof (struct pcontact_info));
765 
766 	pcontact_info_t search_ci;
767 	memset(&ci, 0, sizeof(struct pcontact_info));
768 
769 	sip_uri_t contact_uri;
770         if (parse_uri(uri->s, uri->len, &contact_uri) != 0) {
771             LM_WARN("Failed to parse aor [%.*s]\n", uri->len, uri->s);
772             return -1;
773         }
774 
775         search_ci.received_host.s = received_host->s;
776         search_ci.received_host.len = received_host->len;
777         search_ci.received_port = received_port;
778         search_ci.received_proto = contact_uri.proto? contact_uri.proto : PROTO_UDP;
779         search_ci.searchflag = SEARCH_RECEIVED;
780         search_ci.via_host.s = received_host->s;
781         search_ci.via_host.len = received_host->len;
782         search_ci.via_port = received_port;
783         search_ci.via_prot = search_ci.received_proto;
784         search_ci.aor.s = uri->s;
785         search_ci.aor.len = uri->len;
786 		search_ci.reg_state = PCONTACT_ANY;
787 
788 	if (ul.get_pcontact(_d, &search_ci, &pcontact) == 0) {
789 		/* Lock this record while working with the data: */
790 		ul.lock_udomain(_d, &pcontact->via_host, pcontact->via_port, pcontact->via_proto);
791 
792 		LM_DBG("Updating contact [%.*s]: setting state to PCONTACT_DEREG_PENDING_PUBLISH\n", pcontact->aor.len, pcontact->aor.s);
793 
794 		ci.reg_state = PCONTACT_DEREG_PENDING_PUBLISH;
795 		ci.num_service_routes = 0;
796 		if (ul.update_pcontact(_d, &ci, pcontact) == 0) result = 1;
797 
798 		/* Unlock domain */
799 		ul.unlock_udomain(_d, &pcontact->via_host, pcontact->via_port, pcontact->via_proto);
800 	}
801 	return result;
802 }
803 
804