Skip to content

Commit

Permalink
Fix auth via B2B module.
Browse files Browse the repository at this point in the history
Remove the bogus hooks placed by TM in the outbound SIP buffer (as the buffer may change in local route) and rebuild the B2B invite (with credentials) from the initial sent invite.
Reported by @DMOsipov and @xxReaper on GITHUB.
Closing #577 and #628 .
  • Loading branch information
bogdan-iancu committed Sep 21, 2015
1 parent 6a565b8 commit a6a896f
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 30 deletions.
116 changes: 98 additions & 18 deletions modules/b2b_entities/dlg.c
Expand Up @@ -1988,6 +1988,96 @@ int b2b_send_req(b2b_dlg_t* dlg, enum b2b_entity_type etype,

static struct sip_msg dummy_msg;

static int build_extra_headers_from_msg(str buf, str *extra_hdr,
str *new_hdrs, str *body)
{
struct sip_msg req;
struct hdr_field *hdr;
int len;
char *p;

memset( &req, 0, sizeof(req) );
req.buf = buf.s;
req.len = buf.len;
if (parse_msg(buf.s, buf.len, &req)!=0) {
LM_CRIT("BUG - buffer parsing failed!");
return -1;
}
/* parse all headers */
if (parse_headers(&req, HDR_EOH_F, 0 )<0) {
LM_ERR("parse_headers failed\n");
goto error;
}

/* first calculate the total len */
len = extra_hdr->len;
for( hdr=req.headers; hdr ; hdr=hdr->next ) {
/* skip all headers that are by default added by build_uac_req()
* We want to propagete only custom headers !!! */
switch(hdr->type){
case HDR_VIA_T:
case HDR_TO_T:
case HDR_FROM_T:
case HDR_ROUTE_T:
case HDR_CSEQ_T:
case HDR_CALLID_T:
case HDR_MAXFORWARDS_T:
case HDR_CONTENTLENGTH_T:
case HDR_USERAGENT_T:
break;
default:
/* count the header (includes the CRLF) */
len += hdr->len;
}
}

/* allocate */
new_hdrs->len = len;
new_hdrs->s = pkg_malloc( len );
if (new_hdrs->s==NULL) {
LM_ERR("failed to allocate pkg mem (needed %d)\n",len);
goto error;
}

/* copy headers */
for( p=new_hdrs->s,hdr=req.headers; hdr ; hdr=hdr->next ) {
switch(hdr->type){
case HDR_VIA_T:
case HDR_TO_T:
case HDR_FROM_T:
case HDR_ROUTE_T:
case HDR_CSEQ_T:
case HDR_CALLID_T:
case HDR_MAXFORWARDS_T:
case HDR_CONTENTLENGTH_T:
case HDR_USERAGENT_T:
break;
default:
/* copy the header (includes the CRLF) */
memcpy( p, hdr->name.s , hdr->len);
p += hdr->len;
}
}
/* and extra */
memcpy( p, extra_hdr->s, extra_hdr->len);

if (get_body( &req, body)<0) {
LM_ERR("failed to extract body\n");
pkg_free( new_hdrs->s );
goto error;
}

free_sip_msg(&req);

return 0;
error:
free_sip_msg(&req);
new_hdrs->s = body->s = NULL;
new_hdrs->len = body->len = 0;
return -1;
}


void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps)
{
struct sip_msg * msg;
Expand All @@ -2002,6 +2092,7 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps)
struct to_body* pto;
str to_tag, callid, from_tag;
str extra_headers = {NULL, 0};
str body = {NULL, 0};
struct hdr_field* hdr;
unsigned int method_id = 0;
struct cseq_body cb;
Expand Down Expand Up @@ -2302,32 +2393,21 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps)
lock_release(&htable[hash_index].lock);
goto error;
}
LM_DBG("[%.*s]\n", new_hdr->len, new_hdr->s);
LM_DBG("uri [%.*s] with extra_hdrs [%.*s]\n",
t->uac[0].uri.len, t->uac[0].uri.s,
t->uac[0].extra_headers.len,
t->uac[0].extra_headers.s);
extra_headers.s = (char*)pkg_malloc(new_hdr->len +
t->uac[0].extra_headers.len);
if (extra_headers.s == NULL)
{
LM_ERR("No more private memory\n");
LM_DBG("auth is [%.*s]\n", new_hdr->len, new_hdr->s);
if (build_extra_headers_from_msg(t->uac[0].request.buffer,
new_hdr, &extra_headers, &body) < 0 ) {
LM_ERR("failed to build extra msgs after auth\n");
dlg->state = B2B_TERMINATED;
lock_release(&htable[hash_index].lock);
goto error;
}
memcpy(extra_headers.s, new_hdr->s, new_hdr->len);
memcpy(extra_headers.s + new_hdr->len,
t->uac[0].extra_headers.s,
t->uac[0].extra_headers.len);
extra_headers.len = new_hdr->len +
t->uac[0].extra_headers.len;
LM_DBG("[%.*s]\n", extra_headers.len, extra_headers.s);
LM_DBG("extra is [%.*s]\n",
extra_headers.len, extra_headers.s);
pkg_free(new_hdr->s);
new_hdr->s = NULL; new_hdr->len = 0;

b2b_send_indlg_req(dlg, B2B_CLIENT, b2b_key, &t->method,
&extra_headers, &t->uac[0].body, 0);
&extra_headers, &body, 0);
pkg_free(extra_headers.s);

dlg->state = B2B_NEW_AUTH;
Expand Down
4 changes: 0 additions & 4 deletions modules/tm/h_table.h
Expand Up @@ -148,10 +148,6 @@ typedef struct ua_client
str duri;
/* the path vector used for this branch */
str path_vec;
/* the list of extra headers in the request sent out from a dlg structure */
str extra_headers;
/* the body in the request sent out from a dlg structure */
str body;
/* number of RR headers that were locally added for this branch */
unsigned int added_rr;
/* if we store a reply (branch picking), this is where it is */
Expand Down
16 changes: 8 additions & 8 deletions modules/tm/t_msgbuilder.c
Expand Up @@ -863,17 +863,17 @@ char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog,
append_string(w, user_agent_header.s, user_agent_header.len);
append_string(w, CRLF, CRLF_LEN);
}
if (headers) {
t->uac[branch].extra_headers.s = w;
t->uac[branch].extra_headers.len = headers->len;

/* extra headers (containing CRLF) */
if (headers)
append_string(w, headers->s, headers->len);
}

/* add CRLF between headers and body */
append_string(w, CRLF, CRLF_LEN);
if (body) {
t->uac[branch].body.s = w;
t->uac[branch].body.len = body->len;

/* add body (if required) */
if (body)
append_string(w, body->s, body->len);
}

#ifdef EXTRA_DEBUG
if (w-buf != *len ) abort();
Expand Down

0 comments on commit a6a896f

Please sign in to comment.