more changes around plugin_fix_fbox_anoncall and Contact Header masquerading

This commit is contained in:
Thomas Ries
2016-02-03 20:02:27 +00:00
parent 26fa103921
commit d80848c760
3 changed files with 85 additions and 33 deletions
+45 -15
View File
@@ -107,21 +107,24 @@ int PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){
type = ticket->direction;
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
/* Outgoing SIP response? - may also need to process outgoing SIP requests - */
if ((type == RESTYP_OUTGOING) || (type == REQTYP_OUTGOING)) {
/* a Contact header needs to be present in response */
osip_message_get_contact(ticket->sipmsg, 0, &contact);
if(contact == NULL) {
DEBUGC(DBCLASS_PLUGIN, "no Contact header found in outgoing SIP message");
DEBUGC(DBCLASS_PLUGIN, "no Contact header found in SIP message");
return STS_SUCCESS;
}
if(contact->url == NULL) {
DEBUGC(DBCLASS_PLUGIN, "no Contact->Url header found in outgoing SIP message");
DEBUGC(DBCLASS_PLUGIN, "no Contact->url header found in SIP message");
return STS_SUCCESS;
}
if (contact->url->host == NULL) {
DEBUGC(DBCLASS_PLUGIN, "no Contact->url->host header found in SIP message");
return STS_SUCCESS;
}
/*
@@ -158,6 +161,7 @@ DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
param_match=0;
if (urlmap[idx].active == 0) continue;
if (urlmap[idx].true_url == NULL) continue;
/* outgoing response - only look for true_url */
/* 1) check host, skip of no match */
@@ -167,18 +171,28 @@ DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
continue;
}
}
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: idx=%i, IP/Host match [%s]",
idx, contact->url->host);
/* 2) check username match */
if (contact->url->username && urlmap[idx].true_url->username) {
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: check username: "
"contact->url->username [%s] <-> true_url->username [%s]",
contact->url->username, urlmap[idx].true_url->username);
if (osip_strcasecmp(contact->url->username, urlmap[idx].true_url->username) == 0) {
/* MATCH, all OK - return */
user_match=1;
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: username matches");
break;
}
} else {
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: NULL username: "
"contact->username 0x%p <-> true_url->username 0x%p",
contact->url->username, urlmap[idx].true_url->username);
}
/* 3) check param field ("uniq=" param)*/
if (contact->url && urlmap[idx].true_url) {
{
int sts1, sts2;
osip_uri_param_t *p1=NULL, *p2=NULL;
@@ -186,12 +200,28 @@ DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
sts2=osip_uri_param_get_byname(&(urlmap[idx].true_url->url_params), "uniq", &p2);
if ( ((sts1 == OSIP_SUCCESS) && (sts2 == OSIP_SUCCESS)) &&
(p1 && p2) &&
(p1->gname && p2->gname && p1->gvalue && p2->gvalue) &&
(osip_strcasecmp(p1->gname, p2->gname) == 0) &&
(osip_strcasecmp(p1->gvalue, p2->gvalue) == 0) ) {
/* MATCH */
param_match=1;
param_match_idx=idx;
(p1->gname && p2->gname && p1->gvalue && p2->gvalue) ) {
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: check param: "
"contact-> [%s]=[%s] <-> true_url->[%s]=[%s]",
p1->gname, p1->gvalue, p2->gname, p2->gvalue);
if ((osip_strcasecmp(p1->gname, p2->gname) == 0) &&
(osip_strcasecmp(p1->gvalue, p2->gvalue) == 0) ) {
/* MATCH */
param_match=1;
param_match_idx=idx;
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: uniq param matches");
}
} else {
if (p1 && p2) {
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: NULL param fields: "
"contact-> 0x%p=0x%p <-> true_url->0x%p=0x%p",
p1->gname, p1->gvalue, p2->gname, p2->gvalue);
} else {
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: NULL param: "
"contact->param 0x%p <-> true_url->param 0x%p",
p1, p2);
}
}
}
@@ -205,9 +235,9 @@ DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
/* no partial match (no host, or no user / no param match) */
if (param_match == 0) {
WARN("Bogus outgoing response Contact header from [%s], unable to sanitize!",
utils_inet_ntoa(ticket->from.sin_addr));
return STS_FAILURE;
DEBUGC(DBCLASS_PLUGIN, "Bogus outgoing response Contact header from [%s], "
"unable to sanitize!", utils_inet_ntoa(ticket->from.sin_addr));
return STS_SUCCESS;
}
/* param_match - replace the username part from [param_match_idx] -> Contact */
@@ -224,7 +254,7 @@ DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: type=%i", type);
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: no IP match, returning.");
}
DEBUGC(DBCLASS_PLUGIN, "plugin_fix_fbox_anoncall: done");
} // if (type == RESTYP_OUTGOING)
} // if (type == ..
return STS_SUCCESS;
}
+38 -16
View File
@@ -270,6 +270,7 @@ int compare_url(osip_uri_t *url1, osip_uri_t *url2) {
return STS_FAILURE;
}
#if 0
DEBUGC(DBCLASS_BABBLE, "comparing urls: %s:%s@%s -> %s:%s@%s",
(url1->scheme) ? url1->scheme : "(null)",
(url1->username) ? url1->username : "(null)",
@@ -277,6 +278,7 @@ int compare_url(osip_uri_t *url1, osip_uri_t *url2) {
(url2->scheme) ? url2->scheme : "(null)",
(url2->username) ? url2->username : "(null)",
(url2->host) ? url2->host : "(null)");
#endif
/* compare SCHEME (if present) case INsensitive */
if (url1->scheme && url2->scheme) {
@@ -291,11 +293,11 @@ int compare_url(osip_uri_t *url1, osip_uri_t *url2) {
/* compare username (if present) case sensitive */
if (url1->username && url2->username) {
if (strcmp(url1->username, url2->username) != 0) {
DEBUGC(DBCLASS_BABBLE, "compare_url: username mismatch");
// DEBUGC(DBCLASS_BABBLE, "compare_url: username mismatch");
return STS_FAILURE;
}
} else {
DEBUGC(DBCLASS_BABBLE, "compare_url: NULL username - ignoring");
// DEBUGC(DBCLASS_BABBLE, "compare_url: NULL username - ignoring");
}
@@ -661,6 +663,10 @@ int sip_rewrite_contact (sip_ticket_t *ticket, int direction) {
if (contact == NULL) break;
if (contact->url == NULL) continue;
DEBUGC(DBCLASS_PROXY, "trying to rewriting Contact header %s@%s",
(contact->url->username)? contact->url->username : "*NULL*",
(contact->url->host)? contact->url->host : "*NULL*");
/* search for an entry */
for (i=0;i<URLMAP_SIZE;i++){
if (urlmap[i].active == 0) continue;
@@ -670,16 +676,6 @@ int sip_rewrite_contact (sip_ticket_t *ticket, int direction) {
(compare_url(contact->url, urlmap[i].masq_url)==STS_SUCCESS)) break;
}
/* NOTE:
It has been observed with some UAs (e.g. Fritzbox) that when receiving
an anonymous call (call with supressed CLID) these UAs do send a *modified*
Contact header (compared to the Contact used in REGISTER).
This confuses siproxd as now masquerading cannot match the Contact Header
with the URLMAP table.
-> see plugin_fix_fbox_anoncall that tries to work around things by
detecting this and restoring the "sane" Contact header.
/*
/* found a mapping entry */
if (i<URLMAP_SIZE) {
char *tmp;
@@ -721,6 +717,32 @@ int sip_rewrite_contact (sip_ticket_t *ticket, int direction) {
osip_list_add(&(sip_msg->contacts),contact,j);
replaced=1;
} else {
#if 1
/* FALLBACK - some devices send crappy Contact headers that
* are completely different from the Contact used in REGISTER.
* This is a hack-around, trying *somehow* to produce a "meaningful"
* masqueraded contact header (at least it does point back to the proxy
* and not into some RFC1918 network).
*/
if (direction == DIR_OUTGOING) {
DEBUGC(DBCLASS_PROXY, "outgoing: no match - fallback to plain proxy IP");
struct in_addr addr;
if (get_interface_ip(IF_OUTBOUND, &addr) == STS_SUCCESS) {
char *myaddr;
myaddr=utils_inet_ntoa(addr);
/* Host */
osip_free(contact->url->host);
contact->url->host = osip_strdup(myaddr);
/* Port */
contact->url->port=realloc(contact->url->port, 16);
sprintf(contact->url->port, "%i", configuration.sip_listen_port);
replaced=1;
}
} // if direction
#endif
}
} /* for j */
@@ -941,7 +963,7 @@ int sip_find_outbound_proxy(sip_ticket_t *ticket, struct in_addr *addr,
return STS_FAILURE;
}
*port=atoi(configuration.outbound_proxy_domain_port.string[i]);
if ((*port<=0) || (*port>65535)) *port=SIP_PORT;
// if ((*port<=0) || (*port>65535)) *port=SIP_PORT;
return STS_SUCCESS;
@@ -1029,8 +1051,8 @@ int sip_find_direction(sip_ticket_t *ticket, int *urlidx) {
DEBUGC(DBCLASS_SIP, "sip_find_direction: cannot resolve host [%s]",
urlmap[i].true_url->host);
} else {
DEBUGC(DBCLASS_BABBLE, "sip_find_direction: reghost:%s ip:%s",
urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr));
// DEBUGC(DBCLASS_BABBLE, "sip_find_direction: reghost:%s ip:%s",
// urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr));
if (memcmp(&tmp_addr, &from->sin_addr, sizeof(tmp_addr)) == 0) {
if (MSG_IS_REQUEST(ticket->sipmsg)) {
type=REQTYP_OUTGOING;
@@ -1480,7 +1502,7 @@ int sip_get_received_param(sip_ticket_t *ticket,
/* fetch the port number */
*port = atoi(rport->gvalue);
if ((*port <=0) || (*port >=65536)) return STS_FAILURE;
// if ((*port <=0) || (*port >=65536)) return STS_FAILURE;
/* If TCP, then validate first if an existing connection is in the cache.
* If not, do not use this - a new conection must be established! */
+2 -2
View File
@@ -97,8 +97,8 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
/* check if passed string is already a plain IPv4 address */
if (utils_inet_aton(hostname, addr) > 0) {
/* is a plain IPv4 string - return the result directly, no lookup and cache */
DEBUGC(DBCLASS_BABBLE, "DNS lookup - shortcut, hostname is IP string [%s] -> [%s]",
hostname, utils_inet_ntoa(*addr));
// DEBUGC(DBCLASS_BABBLE, "DNS lookup - shortcut, hostname is IP string [%s] -> [%s]",
// hostname, utils_inet_ntoa(*addr));
return STS_SUCCESS;
}