/** * Look for Security-Verify and delete it if found. * @param msg - the SIP message to add to * @param str1 - not used * @param str2 - not used * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not found or #CSCF_RETURN_FALSE on error */ int P_remove_security_verify(struct sip_msg *msg,char *str1,char*str2) { struct hdr_field *hdr=0; for(hdr=cscf_get_next_header(msg,s_security_verify,0);hdr;hdr=cscf_get_next_header(msg,s_security_verify,hdr)){ if (!cscf_del_header(msg,hdr)){ LOG(L_INFO,"INF:"M_NAME":P_remove_security_verify: Error dropping Security-Client header.\n"); return CSCF_RETURN_ERROR; } } return CSCF_RETURN_TRUE; }
/** * Applies Privacy for P-Asserted-Identity. * @param msg - the SIP message * @returns #CSCF_RETURN_TRUE if privacy applied or #CSCF_RETURN_FALSE if not */ int apply_privacy_id(struct sip_msg* msg){ struct hdr_field *hdr; LOG(L_DBG, "DBG:"M_NAME": apply_privacy_id\n"); hdr = cscf_get_next_header(msg,asserted_identity,NULL); if (!hdr) return CSCF_RETURN_FALSE; do { cscf_del_header(msg,hdr); hdr=cscf_get_next_header(msg,asserted_identity,hdr); } while (hdr); return CSCF_RETURN_TRUE; }
/** * Looks for the prefered Security header . * @param req - the SIP message * @param header_name - SIP header name * @param type - output value of the security type * @param q - output preferate value * @returns the security body for the provided SIP message */ str cscf_get_pref_security_header(struct sip_msg *req, str header_name,r_security_type *type, float *q) { str q_sec={0,0},t_sec; r_security_type q_type=SEC_NONE,t_type; float q_q=-1,t_q; struct hdr_field *hdr=0; str tmp={0,0}; char c; /* first find the highest q */ for(hdr = cscf_get_next_header(req,header_name,(void*)0);hdr;hdr = cscf_get_next_header(req,header_name,hdr)){ t_sec = hdr->body; /* if unknown type, skip */ t_type = cscf_get_security_type(t_sec); if (t_type==SEC_NONE || (!pcscf_use_ipsec&&t_type==SEC_IPSEC)|| (!pcscf_use_tls&&t_type==SEC_TLS)) continue; /* check if q is maximum */ get_param(t_sec,s_q,tmp); if (tmp.len) { c = tmp.s[tmp.len]; tmp.s[tmp.len]=0; t_q = atof(tmp.s); tmp.s[tmp.len]=c; } else t_q = -1; if (t_q > q_q || q_sec.len==0) { q_sec = t_sec; q_q = t_q; q_type = t_type; } } if (!q_sec.len) { LOG(L_INFO,"DBG:"M_NAME":cscf_get_pref_security_header: No known Security header found.\n"); return q_sec; } if (type) *type = q_type; if (q) *q = q_q; return q_sec; }
/** * Remove from <str1> headers the <str2> tag * \note Does not work if you call it multiple times for the same hdr_name! * \note Because of the note above, this needs a fix to accept multiple tags in the str2 parameter! * @param msg - SIP Request * @param str1 - the header to remove from * @param str2 - the tag to remove * @returns #CSCF_RETURN_TRUE if removed, #CSCF_RETURN_FALSE if no changes required or #CSCF_RETURN_FALSE on error */ int P_remove_header_tag(struct sip_msg *msg,char *str1, char *str2) { str hdr_name,tag,x,y; struct hdr_field *hdr; char *c; int found,i,j,changed=0; hdr_name.s = str1; hdr_name.len = strlen(str1); tag.s = str2; tag.len = strlen(str2); hdr = cscf_get_header(msg,hdr_name); while (hdr){ /* get the original body */ x = hdr->body; LOG(L_INFO,"DBG:"M_NAME":P_remove_header_tag(): Original <%.*s> -> <%.*s>\n", hdr_name.len,hdr_name.s,x.len,x.s); /* duplicate the original body */ x.len++; STR_PKG_DUP(y,x,"P_remove_header_tag"); if (!y.s) goto error; y.len--; y.s[y.len]=0; /* look for occurences of tag and overwrite with \0 */ found=0; c = strtok(y.s," \t\r\n,"); while (c){ if (strlen(c)==tag.len && strncasecmp(c,tag.s,tag.len)==0){ found++; memset(c,0,tag.len); } c = strtok(0," \t\r\n,"); } /* if not found just skip to next header */ if (!found) goto next; /* compact the remaining tags by removing the \0 */ for(i=0,j=0;i<y.len;i++) if (y.s[i]!=0){ y.s[j++]=y.s[i]; } else { if (j!=0) y.s[j++]=','; while(i+1<y.len && y.s[i+1]==0) i++; } y.len = j; if (y.s[y.len-1]==',') y.len--; LOG(L_INFO,"DBG:"M_NAME":P_remove_header_tag(): Modified <%.*s> -> <%.*s>\n", hdr_name.len,hdr_name.s,y.len,y.s); /* write the changes */ if (y.len){ /* replace just the content */ if (!cscf_replace_string(msg,x,y)){ LOG(L_ERR,"ERR:"M_NAME":P_remove_header_tag(): Error replacing string!\n"); if (y.s) pkg_free(y.s); goto error; } }else{ /* remove the whole header */ if (y.s) pkg_free(y.s); if (!cscf_del_header(msg,hdr)){ LOG(L_ERR,"ERR:"M_NAME":P_remove_header_tag(): Error removing the whole header!\n"); goto error; } } changed++; next: hdr = cscf_get_next_header(msg,hdr_name,hdr); } return changed?CSCF_RETURN_TRUE:CSCF_RETURN_FALSE; error: out_of_memory: return CSCF_RETURN_ERROR; }