/** * checked if passed identity is an asserted identity */ int assert_identity(struct sip_msg* _m, udomain_t* _d, str identity) { // Public identities of this contact struct ppublic * p; //remove <> braces if there are if(identity.s[0]=='<' && identity.s[identity.len-1]=='>') { identity.s++; identity.len -= 2; } LM_DBG("Identity to assert: %.*s\n", identity.len, identity.s); if (getContactP(_m, _d, PCONTACT_REGISTERED|PCONTACT_REG_PENDING_AAR|PCONTACT_REG_PENDING, 0, 0) != NULL) { for (p = c->head; p; p = p->next) { LM_DBG("Public identity: %.*s\n", p->public_identity.len, p->public_identity.s); /* Check length: */ if (identity.len == p->public_identity.len) { /* Check contents: */ if (strncasecmp(identity.s, p->public_identity.s, identity.len) == 0) { LM_DBG("Match!\n"); return 1; } } else LM_DBG("Length does not match.\n"); } } LM_INFO("Contact not found based on Contact, trying IP/Port/Proto\n"); str received_host = {0, 0}; char srcip[50]; received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip)); received_host.s = srcip; if (ul.assert_identity(_d, &received_host, _m->rcv.src_port, _m->rcv.proto, &identity) == 0) return -1; else return 1; }
/** * Add proper asserted identies based on registration */ int assert_identity(struct sip_msg* _m, udomain_t* _d, str identity) { // Get the contact: pcontact_t * c = getContactP(_m, _d); // Public identities of this contact ppublic_t * p; // Contact not found => Identity not asserted. if (c == NULL) return -2; /* Lock this record while working with the data: */ ul.lock_udomain(_d, &c->aor); LM_DBG("Checking identity: %.*s\n", identity.len, identity.s); LM_DBG("AOR of contact: %.*s\n", c->aor.len, c->aor.s); for (p = c->head; p; p = p->next) { LM_DBG("Public identity: %.*s\n", p->public_identity.len, p->public_identity.s); /* Check length: */ if (identity.len == p->public_identity.len) { /* Check contents: */ if (strncasecmp(identity.s, p->public_identity.s, identity.len) != 0) { LM_DBG("Match!\n"); goto success; } } else LM_DBG("Length does not match.\n"); } // We should only get here, if we failed: /* Unlock domain */ ul.unlock_udomain(_d, &c->aor); return -1; success: /* Unlock domain */ ul.unlock_udomain(_d, &c->aor); return 1; }
/** * Check, if source is registered. */ int is_registered(struct sip_msg* _m, udomain_t* _d) { if (getContactP(_m, _d, PCONTACT_REGISTERED, 0 ,0) != NULL) return 1; return -1; }
/** * Force Service routes (upon request) */ int force_service_routes(struct sip_msg* _m, udomain_t* _d) { struct hdr_field *it; int i; str new_route_header; struct lump* lmp = NULL; char * buf; pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED,0 ,0); // char srcip[20]; // str received_host; struct via_body* vb; unsigned short port; unsigned short proto; // Contact not found => not following service-routes if (c == NULL) return -1; /* we need to be sure we have seen all HFs */ parse_headers(_m, HDR_EOH_F, 0); vb = cscf_get_ue_via(_m); port = vb->port?vb->port:5060; proto = vb->proto; /* Save current buffer */ buf = _m->buf; // Delete old Route headers: if (_m->route) { for (it = _m->route; it; it = it->next) { if (it->type == HDR_ROUTE_T) { if ((lmp = del_lump(_m, it->name.s - buf, it->len, HDR_ROUTE_T)) == 0) { LM_ERR("del_lump failed \n"); return -1; } } } } /* Reset dst_uri if previously set either by loose route or manually */ if (_m->dst_uri.s && _m->dst_uri.len) { pkg_free(_m->dst_uri.s); _m->dst_uri.s = NULL; _m->dst_uri.len = 0; } // received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip)); // received_host.s = srcip; /* Lock this record while working with the data: */ ul.lock_udomain(_d, &vb->host, port, proto); if (c->num_service_routes > 0) { /* Create anchor for new Route-Header: */ lmp = anchor_lump(_m, _m->headers->name.s - buf,0,0); if (lmp == 0) { LM_ERR("Failed to get anchor lump\n"); goto error; } /* Calculate the length: */ new_route_header.len = route_start.len + route_end.len + (c->num_service_routes-1) * route_sep.len; for(i=0; i< c->num_service_routes; i++) new_route_header.len+=c->service_routes[i].len; /* Allocate the memory for this new header: */ new_route_header.s = pkg_malloc(new_route_header.len); if (!new_route_header.s) { LM_ERR("Error allocating %d bytes\n", new_route_header.len); goto error; } /* Construct new header */ new_route_header.len = 0; STR_APPEND(new_route_header, route_start); for(i=0; i < c->num_service_routes; i++) { if (i) STR_APPEND(new_route_header, route_sep); STR_APPEND(new_route_header, c->service_routes[i]); } STR_APPEND(new_route_header, route_end); LM_DBG("Setting route header to <%.*s> \n", new_route_header.len, new_route_header.s); if ((lmp = insert_new_lump_after(lmp, new_route_header.s, new_route_header.len, HDR_ROUTE_T)) == 0) { LM_ERR("Error inserting new route set\n"); pkg_free(new_route_header.s); goto error; } LM_DBG("Setting dst_uri to <%.*s> \n", c->service_routes[0].len, c->service_routes[0].s); if (set_dst_uri(_m, &c->service_routes[0]) !=0 ) { LM_ERR("Error setting new dst uri\n"); goto error; } } /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return 1; error: /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return -1; return 1; }
/** * Check, if a user-agent follows the indicated service-routes */ int check_service_routes(struct sip_msg* _m, udomain_t* _d) { struct sip_uri uri; int i; struct hdr_field *hdr; rr_t *r; char routes[MAXROUTES][MAXROUTESIZE]; unsigned int num_routes = 0; struct via_body * vb; unsigned short port; unsigned short proto; /* Contact not found => not following service-routes */ // if (c == NULL) return -1; /* Search for the first Route-Header: */ if (find_first_route(_m) < 0) return -1; // LM_DBG("Got %i Route-Headers.\n", c->num_service_routes); vb = cscf_get_ue_via(_m); port = vb->port?vb->port:5060; proto = vb->proto; /* Lock this record while working with the data: */ ul.lock_udomain(_d, &vb->host, port, proto); if (_m->route) { hdr = _m->route; r = (rr_t*)hdr->parsed; //get rid of ourselves from route header if (r) { LM_DBG("Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); while (r && (parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri) == 0) && check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) { LM_DBG("Self\n"); /* Check for more headers and fail, if it was the last one Check, if service-routes are indicated. If yes, request is not following service-routes */ if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; LM_DBG("hdr is %p\n", hdr); LM_DBG("r is %p\n", r); if (r) LM_DBG("Next Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); } int i = 0; while (r) { memset(routes[i],0,MAXROUTESIZE); memcpy(routes[i], r->nameaddr.uri.s, r->nameaddr.uri.len); if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; i += 1; num_routes += 1; } LM_DBG("num_routes is %d\n", num_routes); for (i=0; i<num_routes; i++) { LM_DBG("route %d for checking is %s\n", i, routes[i]); } pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED, routes, num_routes); if (!c) { LM_DBG("no contact found in usrloc when checking for service route\n"); goto error; } LM_DBG("we have a contact which satisifes the routes...\n"); ul.unlock_udomain(_d, &vb->host, port, proto); return 1; } } else { LM_DBG("Request doesn't have any route headers to check service-route...ignoring\n"); goto error; } pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED, 0, 0); if (!c) { LM_DBG("no contact found in usrloc when checking for service route\n"); goto error; } /* Check the route-set: */ if (_m->route) { hdr = _m->route; LM_DBG("hdr is %p\n", hdr); /* Check, if the first host is ourself: */ r = (rr_t*)hdr->parsed; if (r) { LM_DBG("Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); /* Skip first headers containing myself: */ while (r && (parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri) == 0) && check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) { LM_DBG("Self\n"); /* Check for more headers and fail, if it was the last one Check, if service-routes are indicated. If yes, request is not following service-routes */ if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; if (!r && (c->num_service_routes > 0)) { LM_DBG("Not enough route-headers in Message\n"); goto error; } LM_DBG("hdr is %p\n", hdr); LM_DBG("r is %p\n", r); if (r) LM_DBG("Next Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); } LM_DBG("We have %d service-routes\n", c->num_service_routes); /* Then check the following headers: */ for (i=0; i< c->num_service_routes; i++) { LM_DBG("Route must be: %.*s\n", c->service_routes[i].len, c->service_routes[i].s); /* No more Route-Headers? Not following service-routes */ if (!r) { LM_DBG("No more route headers in message.\n"); goto error; } LM_DBG("Route is: %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); /* Check length: */ if (r->nameaddr.uri.len != c->service_routes[i].len) { LM_DBG("Length does not match.\n"); goto error; } /* Check contents: */ if (strncasecmp(r->nameaddr.uri.s, c->service_routes[i].s, c->service_routes[i].len) != 0) { LM_DBG("String comparison failed.\n"); goto error; } if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; } /* Check, if it was the last route-header in the message: */ if (r) { LM_DBG("Too many route headers in message.\n"); goto error; } } else { LM_WARN("Strange: Route-Header is present, but not parsed?!?"); if (c->num_service_routes > 0) goto error; } } else { LM_DBG("No route header in Message.\n"); /* No route-header? Check, if service-routes are indicated. If yes, request is not following service-routes */ if (c->num_service_routes > 0) goto error; } /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return 1; error: /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return -1; }
/** * Check, if source is registered. */ int is_registered(struct sip_msg* _m, udomain_t* _d) { if (getContactP(_m, _d) != NULL) return 1; return -1; }
/** * Check, if a user-agent follows the indicated service-routes */ int check_service_routes(struct sip_msg* _m, udomain_t* _d) { struct sip_uri uri; int i; struct hdr_field *hdr; rr_t *r; pcontact_t * c = getContactP(_m, _d); /* Contact not found => not following service-routes */ if (c == NULL) return -1; /* Search for the first Route-Header: */ if (find_first_route(_m) < 0) return -1; LM_DBG("Got %i Route-Headers.\n", c->num_service_routes); /* Lock this record while working with the data: */ ul.lock_udomain(_d, &c->aor); /* Check the route-set: */ if (_m->route) { hdr = _m->route; LM_DBG("hdr is %p\n", hdr); /* Check, if the first host is ourself: */ r = (rr_t*)hdr->parsed; if (r) { LM_DBG("Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); /* Skip first headers containing myself: */ while (parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri) == 0 && check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) { LM_DBG("Self\n"); /* Check for more headers and fail, if it was the last one Check, if service-routes are indicated. If yes, request is not following service-routes */ if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; if (!r && (c->num_service_routes > 0)) { LM_DBG("Not enough route-headers in Message\n"); goto error; } LM_DBG("hdr is %p\n", hdr); LM_DBG("r is %p\n", r); if (r) LM_DBG("Next Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); } /* Then check the following headers: */ for (i=0; i< c->num_service_routes; i++) { LM_DBG("Route must be: %.*s\n", c->service_routes[i].len, c->service_routes[i].s); /* No more Route-Headers? Not following service-routes */ if (!r) { LM_ERR("No more route headers in message.\n"); goto error; } LM_DBG("Route is: %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); /* Check length: */ if (r->nameaddr.uri.len != c->service_routes[i].len) { LM_DBG("Length does not match.\n"); goto error; } /* Check contents: */ if (strncasecmp(r->nameaddr.uri.s, c->service_routes[i].s, c->service_routes[i].len) != 0) { LM_DBG("String comparison failed.\n"); goto error; } if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; } /* Check, if it was the last route-header in the message: */ if (r) { LM_ERR("Too many route headers in message.\n"); goto error; } } else { LM_WARN("Strange: Route-Header is present, but not parsed?!?"); if (c->num_service_routes > 0) goto error; } } else { LM_ERR("No route header in Message.\n"); /* No route-header? Check, if service-routes are indicated. If yes, request is not following service-routes */ if (c->num_service_routes > 0) goto error; } /* Unlock domain */ ul.unlock_udomain(_d, &c->aor); return 1; error: /* Unlock domain */ ul.unlock_udomain(_d, &c->aor); return -1; }
/** * Check, if a user-agent follows the indicated service-routes */ int check_service_routes(struct sip_msg* _m, udomain_t* _d) { struct sip_uri uri; int i; struct hdr_field *hdr; rr_t *r; // char srcip[20]; // str received_host; struct via_body * vb; unsigned short port; unsigned short proto; /* Contact not found => not following service-routes */ if (c == NULL) return -1; /* Search for the first Route-Header: */ if (find_first_route(_m) < 0) return -1; LM_DBG("Got %i Route-Headers.\n", c->num_service_routes); // received_host.len = ip_addr2sbuf(&_m->rcv.src_ip, srcip, sizeof(srcip)); // received_host.s = srcip; vb = cscf_get_ue_via(_m); port = vb->port?vb->port:5060; proto = vb->proto; /* Lock this record while working with the data: */ ul.lock_udomain(_d, &vb->host, port, proto); pcontact_t * c = getContactP(_m, _d, PCONTACT_REGISTERED); if (!c) { LM_DBG("no contact found in usrloc when checking for service route\n"); goto error; } /* Check the route-set: */ if (_m->route) { hdr = _m->route; LM_DBG("hdr is %p\n", hdr); /* Check, if the first host is ourself: */ r = (rr_t*)hdr->parsed; if (r) { LM_DBG("Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); /* Skip first headers containing myself: */ while (r && (parse_uri(r->nameaddr.uri.s, r->nameaddr.uri.len, &uri) == 0) && check_self(&uri.host,uri.port_no?uri.port_no:SIP_PORT,0)) { LM_DBG("Self\n"); /* Check for more headers and fail, if it was the last one Check, if service-routes are indicated. If yes, request is not following service-routes */ if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; if (!r && (c->num_service_routes > 0)) { LM_DBG("Not enough route-headers in Message\n"); goto error; } LM_DBG("hdr is %p\n", hdr); LM_DBG("r is %p\n", r); if (r) LM_DBG("Next Route is %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); } LM_DBG("We have %d service-routes\n", c->num_service_routes); /* Then check the following headers: */ for (i=0; i< c->num_service_routes; i++) { LM_DBG("Route must be: %.*s\n", c->service_routes[i].len, c->service_routes[i].s); /* No more Route-Headers? Not following service-routes */ if (!r) { LM_DBG("No more route headers in message.\n"); goto error; } LM_DBG("Route is: %.*s\n", r->nameaddr.uri.len, r->nameaddr.uri.s); /* Check length: */ if (r->nameaddr.uri.len != c->service_routes[i].len) { LM_DBG("Length does not match.\n"); goto error; } /* Check contents: */ if (strncasecmp(r->nameaddr.uri.s, c->service_routes[i].s, c->service_routes[i].len) != 0) { LM_DBG("String comparison failed.\n"); goto error; } if (find_next_route(_m, &hdr) != 0) r = NULL; else r = (rr_t*)hdr->parsed; } /* Check, if it was the last route-header in the message: */ if (r) { LM_DBG("Too many route headers in message.\n"); goto error; } } else { LM_WARN("Strange: Route-Header is present, but not parsed?!?"); if (c->num_service_routes > 0) goto error; } } else { LM_DBG("No route header in Message.\n"); /* No route-header? Check, if service-routes are indicated. If yes, request is not following service-routes */ if (c->num_service_routes > 0) goto error; } /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return 1; error: /* Unlock domain */ ul.unlock_udomain(_d, &vb->host, port, proto); return -1; }
/** * Check, if source is registered. */ int is_registered(struct sip_msg* _m, udomain_t* _d) { if (getContactP(_m, _d) != NULL) return 1; //I think Carsten wrote this but IMO it should be based on Via, not received IP // if (getContactP_from_via(_m, _d) != NULL) return 1; // It was really intended that way :-) return -1; }