Skip to content

Commit

Permalink
Merge pull request #1964 from alexyosifov/registrar_pcscf_sec_agree
Browse files Browse the repository at this point in the history
ims_registrar_pcscf: parse security verify header
  • Loading branch information
miconda committed May 28, 2019
2 parents 8351df3 + 6845772 commit 6c902f5
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 17 deletions.
24 changes: 23 additions & 1 deletion src/modules/ims_registrar_pcscf/save.c
Expand Up @@ -291,7 +291,8 @@ int save_pending(struct sip_msg* _m, udomain_t* _d) {
LM_DBG("not doing pending reg on de-registration\n");
return 1;
}
LM_DBG("Save Pending");

LM_DBG("Save pending contact with AOR [%.*s], proto %d, port %d\n", c->uri.len, c->uri.s, proto, port);
LM_DBG("contact requesting to expire in %d seconds\n", expires-local_time_now);

/*populate CI with bare minimum*/
Expand Down Expand Up @@ -339,6 +340,21 @@ int save_pending(struct sip_msg* _m, udomain_t* _d) {
LM_ERR("Will save pending contact without security parameters\n");
}

// Parse security-verify parameters
security_t* sec_verify_params = NULL;
if((sec_verify_params = cscf_get_security_verify(_m)) == NULL){
LM_ERR("Will save pending contact without security-verify parameters\n");
}else{
if(sec_params){
// for REGISTER request try to set spi pc and spi ps from security-verify header
sec_params->data.ipsec->spi_ps = sec_verify_params->data.ipsec->spi_us;
sec_params->data.ipsec->spi_pc = sec_verify_params->data.ipsec->spi_uc;

LM_DBG("Will save pending contact with security-verify parameters, spc_ps %u, spi_pc %u\n",
sec_params->data.ipsec->spi_ps, sec_params->data.ipsec->spi_pc);
}
}

ul.lock_udomain(_d, &ci.via_host, ci.via_port, ci.via_prot);
if (ul.get_pcontact(_d, &ci, &pcontact) != 0) { //need to insert new contact
LM_DBG("Adding pending pcontact: <%.*s>\n", c->uri.len, c->uri.s);
Expand Down Expand Up @@ -428,6 +444,12 @@ int save(struct sip_msg* _m, udomain_t* _d, int _cflags) {
cscf_get_p_associated_uri(_m, &public_ids, &num_public_ids, 1);
service_routes = cscf_get_service_route(_m, &num_service_routes, 1);

{
struct via_body* vb = cscf_get_ue_via(_m);
LM_DBG("Save contact with AOR(uri) [%.*s], proto %d, port %d\n",
cb->contacts->uri.len, cb->contacts->uri.s, vb->proto, vb->port?vb->port:5060);
}

//update contacts
if (!update_contacts(req, _m, _d, cb->star, expires_hdr, public_ids, num_public_ids, service_routes, num_service_routes, 0)) {
LM_ERR("failed to update pcontact\n");
Expand Down
66 changes: 50 additions & 16 deletions src/modules/ims_registrar_pcscf/sec_agree.c
Expand Up @@ -46,6 +46,18 @@ static uint32_t parse_digits(str value)
return ret;
}

static void trim_whitespaces(str* string) {
// skip leading whitespace
while(string->len && (string->s[0]==' ' || string->s[0]=='\t' || string->s[0]=='<')){
string->s = string->s + 1;
string->len --;
}

// skip trailing whitespace
while(string->len && (string->s[string->len-1]==' ' || string->s[string->len-1]=='\t')){
string->len--;
}
}

#define SEC_COPY_STR_PARAM(DST, SRC)\
DST.s = shm_malloc(SRC.len);\
Expand All @@ -58,6 +70,8 @@ static uint32_t parse_digits(str value)

static int process_sec_agree_param(str name, str value, ipsec_t *ret)
{
trim_whitespaces(&name);
trim_whitespaces(&value);

if(strncasecmp(name.s, "alg", name.len) == 0) {
SEC_COPY_STR_PARAM(ret->r_alg, value);
Expand Down Expand Up @@ -100,18 +114,9 @@ static security_t* parse_sec_agree(struct hdr_field* h)
security_t* params = NULL;
str body = h->body;

// skip leading whitespace
while(body.len && (body.s[0]==' ' || body.s[0]=='\t' || body.s[0]=='<')){
body.s = body.s + 1;
body.len --;
}
trim_whitespaces(&body);

// skip trailing whitespace
while(body.len && (body.s[body.len-1]==' ' || body.s[body.len-1]=='\t')){
body.len--;
}

// skip header name - noone seems to need it
// find mechanism name end
for(i = 0; body.s[i] != ';' && i < body.len; i++);

mechanism_name.s = body.s;
Expand Down Expand Up @@ -227,12 +232,11 @@ static security_t* parse_sec_agree(struct hdr_field* h)


static str s_security_client={"Security-Client",15};
static str s_security_server={"Security-Server",15};
//static str s_security_server={"Security-Server",15};
static str s_security_verify={"Security-Verify",15};
/**
* Looks for the Security-Client header
* @param msg - the sip message
* @param hr - ptr to return the found hdr_field
* @param params - ptr to struct sec_agree_params, where parsed values will be saved
* @returns 0 on success, error code on failure
*/
Expand All @@ -249,9 +253,7 @@ security_t* cscf_get_security(struct sip_msg *msg)
h = msg->headers;
while(h)
{
if ((h->name.len == s_security_client.len && strncasecmp(h->name.s, s_security_client.s, s_security_client.len)==0) ||
(h->name.len == s_security_server.len && strncasecmp(h->name.s, s_security_server.s, s_security_server.len)==0) ||
(h->name.len == s_security_verify.len && strncasecmp(h->name.s, s_security_verify.s, s_security_verify.len)==0) )
if (h->name.len == s_security_client.len && strncasecmp(h->name.s, s_security_client.s, s_security_client.len)==0)
{
return parse_sec_agree(h);
}
Expand All @@ -263,3 +265,35 @@ security_t* cscf_get_security(struct sip_msg *msg)

return NULL;
}

/**
* Looks for the Security-Verify header
* @param msg - the sip message
* @param params - ptr to struct sec_agree_params, where parsed values will be saved
* @returns 0 on success, error code on failure
*/
security_t* cscf_get_security_verify(struct sip_msg *msg)
{
struct hdr_field *h = NULL;

if (!msg) return NULL;

if (parse_headers(msg, HDR_EOH_F, 0)<0) {
return NULL;
}

h = msg->headers;
while(h)
{
if (h->name.len == s_security_verify.len && strncasecmp(h->name.s, s_security_verify.s, s_security_verify.len)==0)
{
return parse_sec_agree(h);
}

h = h->next;
}

LM_INFO("No security-verify parameters found\n");

return NULL;
}
8 changes: 8 additions & 0 deletions src/modules/ims_registrar_pcscf/sec_agree.h
Expand Up @@ -32,4 +32,12 @@
*/
security_t* cscf_get_security(struct sip_msg *msg);

/**
* Looks for the Security-Verify header
* @param msg - the sip message
* @param params - ptr to struct sec_agree_params, where parsed values will be saved
* @returns 0 on success, error code on failure
*/
security_t* cscf_get_security_verify(struct sip_msg *msg);

#endif // SEC_AGREE_H

0 comments on commit 6c902f5

Please sign in to comment.