Skip to content

Commit

Permalink
topology_hiding: properly quote contact hdr params
Browse files Browse the repository at this point in the history
Thanks go to @manojmth for reporting this on GitHub

Close #3090

(cherry picked from commit e767b87)
  • Loading branch information
razvancrainea committed Jun 2, 2023
1 parent ff34e61 commit e23be5d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 82 deletions.
128 changes: 46 additions & 82 deletions modules/topology_hiding/topo_hiding_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,36 @@ static struct lump* delete_existing_contact(struct sip_msg *msg, int del_hdr)
return lump;
}

static inline int topo_ct_param_len(str *name, str *val, int should_quote)
{
int len = 1 /* ; */ + name->len;
if (val->len) {
if (should_quote && should_quote_contact_param_value(val))
len += 2; /* quotes */
len += 1 /* = */ + val->len;
}
return len;
}

static char * topo_ct_param_copy(char *buf, str *name, str *val, int should_quote)
{
*buf++ = ';';
memcpy(buf, name->s, name->len);
buf += name->len;
if (val->len) {
*buf++ = '=';
if (should_quote)
should_quote = should_quote_contact_param_value(val);
if (should_quote)
*buf++ = '"';
memcpy(buf, val->s, val->len);
buf += val->len;
if (should_quote)
*buf++ = '"';
}
return buf;
}

static int topo_dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg, int leg)
{
char *prefix=NULL,*suffix=NULL,*p,*p_init,*ct_username=NULL;
Expand Down Expand Up @@ -448,16 +478,8 @@ static int topo_dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg, i
for (el=th_param_list;el;el=el->next) {
/* we just iterate over the unknown params */
for (i=0;i<ctu.u_params_no;i++) {
if (el->param_name.len == ctu.u_name[i].len &&
(memcmp(el->param_name.s,ctu.u_name[i].s,
el->param_name.len) == 0)) {
if (ctu.u_val[i].len)
suffix_len += 1 /* ; */ + ctu.u_name[i].len +
ctu.u_val[i].len + 1; /* = and value */
else
suffix_len += 1 /* ; */ + ctu.u_name[i].len;
}

if (str_match(&el->param_name, &ctu.u_name[i]))
suffix_len += topo_ct_param_len(&ctu.u_name[i], &ctu.u_val[i], 0);
}
}
}
Expand All @@ -472,14 +494,8 @@ static int topo_dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg, i
} else {
for (el=th_hdr_param_list;el;el=el->next) {
for (it=((contact_body_t *)msg->contact->parsed)->contacts->params;it;it=it->next) {
if (it->name.len == el->param_name.len &&
(memcmp(it->name.s,el->param_name.s,it->name.len) == 0)) {
if (it->body.len)
suffix_len += 1 /* ; */ + it->name.len +
it->body.len + 1; /* = and value */
else
suffix_len += 1 /* ; */ + it->name.len;
}
if (str_match(&el->param_name, &it->name))
suffix_len += topo_ct_param_len(&it->name, &it->body, 1);
}
}
}
Expand Down Expand Up @@ -553,18 +569,8 @@ static int topo_dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg, i
for (el=th_param_list;el;el=el->next) {
/* we just iterate over the unknown params */
for (i=0;i<ctu.u_params_no;i++) {
if (el->param_name.len == ctu.u_name[i].len &&
memcmp(el->param_name.s,ctu.u_name[i].s,
el->param_name.len) == 0) {
*p++ = ';';
memcpy(p,ctu.u_name[i].s,ctu.u_name[i].len);
p+=ctu.u_name[i].len;
if (ctu.u_val[i].len) {
*p++ = '=';
memcpy(p,ctu.u_val[i].s,ctu.u_val[i].len);
p+=ctu.u_val[i].len;
}
}
if (str_match(&el->param_name, &ctu.u_name[i]))
p = topo_ct_param_copy(p, &ctu.u_name[i], &ctu.u_val[i], 0);
}
}
}
Expand All @@ -578,17 +584,8 @@ static int topo_dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg, i
} else {
for (el=th_hdr_param_list;el;el=el->next) {
for (it=((contact_body_t *)msg->contact->parsed)->contacts->params;it;it=it->next) {
if (it->name.len == el->param_name.len &&
(memcmp(it->name.s,el->param_name.s,it->name.len) == 0)) {
*p++ = ';';
memcpy(p,it->name.s,it->name.len);
p += it->name.len;
if (it->body.len) {
*p++ = '=';
memcpy(p,it->body.s,it->body.len);
p += it->body.len;
}
}
if (str_match(&el->param_name, &it->name))
p = topo_ct_param_copy(p, &it->name, &it->body, 1);
}
}
}
Expand Down Expand Up @@ -1620,16 +1617,8 @@ static char* build_encoded_contact_suffix(struct sip_msg* msg,int *suffix_len)
for (el=th_param_list;el;el=el->next) {
/* we just iterate over the unknown params */
for (i=0;i<ctu.u_params_no;i++) {
if (el->param_name.len == ctu.u_name[i].len &&
(memcmp(el->param_name.s,ctu.u_name[i].s,
el->param_name.len) == 0)) {
if (ctu.u_val[i].len)
total_len += 1 /* ; */ + ctu.u_name[i].len +
ctu.u_val[i].len + 1; /* = and value */
else
total_len += 1 /* ; */ + ctu.u_name[i].len;
}

if (str_match(&el->param_name, &ctu.u_name[i]))
suffix_len += topo_ct_param_len(&ctu.u_name[i], &ctu.u_val[i], 0);
}
}
}
Expand All @@ -1644,14 +1633,8 @@ static char* build_encoded_contact_suffix(struct sip_msg* msg,int *suffix_len)
} else {
for (el=th_hdr_param_list;el;el=el->next) {
for (it=((contact_body_t *)msg->contact->parsed)->contacts->params;it;it=it->next) {
if (it->name.len == el->param_name.len &&
(memcmp(it->name.s,el->param_name.s,it->name.len) == 0)) {
if (it->body.len)
total_len += 1 /* ; */ + it->name.len +
it->body.len + 1; /* = and value */
else
total_len += 1 /* ; */ + it->name.len;
}
if (str_match(&el->param_name, &it->name))
suffix_len += topo_ct_param_len(&it->name, &it->body, 1);
}
}
}
Expand Down Expand Up @@ -1703,18 +1686,8 @@ static char* build_encoded_contact_suffix(struct sip_msg* msg,int *suffix_len)
for (el=th_param_list;el;el=el->next) {
/* we just iterate over the unknown params */
for (i=0;i<ctu.u_params_no;i++) {
if (el->param_name.len == ctu.u_name[i].len &&
memcmp(el->param_name.s,ctu.u_name[i].s,
el->param_name.len) == 0) {
*s++ = ';';
memcpy(s,ctu.u_name[i].s,ctu.u_name[i].len);
s+=ctu.u_name[i].len;
if (ctu.u_val[i].len) {
*s++ = '=';
memcpy(s,ctu.u_val[i].s,ctu.u_val[i].len);
s+=ctu.u_val[i].len;
}
}
if (str_match(&el->param_name, &ctu.u_name[i]))
s = topo_ct_param_copy(s, &ctu.u_name[i], &ctu.u_val[i], 0);
}
}
}
Expand All @@ -1727,17 +1700,8 @@ static char* build_encoded_contact_suffix(struct sip_msg* msg,int *suffix_len)
} else {
for (el=th_hdr_param_list;el;el=el->next) {
for (it=((contact_body_t *)msg->contact->parsed)->contacts->params;it;it=it->next) {
if (it->name.len == el->param_name.len &&
(memcmp(it->name.s,el->param_name.s,it->name.len) == 0)) {
*s++ = ';';
memcpy(s,it->name.s,it->name.len);
s += it->name.len;
if (it->body.len) {
*s++ = '=';
memcpy(s,it->body.s,it->body.len);
s += it->body.len;
}
}
if (str_match(&el->param_name, &it->name))
s = topo_ct_param_copy(s, &it->name, &it->body, 1);
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions parser/contact/parse_contact.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "../../dprint.h"
#include "../../trim.h" /* trim_leading */
#include "../../errinfo.h" /* trim_leading */
#include "../../ut.h" /* _isalnum */
#include "parse_contact.h"


Expand Down Expand Up @@ -225,3 +226,29 @@ int contact_iterator(contact_t** c, struct sip_msg* msg, contact_t* prev)
return 0;
}
}

int should_quote_contact_param_value(str *val)
{
char *p, *end = val->s + val->len;
for (p = val->s; p < end; p++) {
if (_isalnum(*p))
continue;
switch (*p) {
/* token chars */
case '-':
case '.':
case '!':
case '%':
case '*':
case '_':
case '+':
case '`':
case '\'':
case '~':
break;
default:
return 1;
}
}
return 0;
}
5 changes: 5 additions & 0 deletions parser/contact/parse_contact.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ void log_contact(contact_body_t* _c);
int contact_iterator(contact_t** c, struct sip_msg* msg, contact_t* prev);


/*
* Indicates whether the param's value should be quoted
*/
int should_quote_contact_param_value(str *val);

#endif /* PARSE_CONTACT_H */

0 comments on commit e23be5d

Please sign in to comment.