/** * Checks if a request comes from a trusted domain. * If not calls function to respond with 403 to REGISTER or clean the message of * untrusted headers * @param msg - the SIP message * @param str1 - not used * @param str2 - not used * @returns #CSCF_RETURN_TRUE if trusted, #CSCF_RETURN_FALSE if not , #CSCF_RETURN_ERROR on REGISTER or error */ int I_NDS_check_trusted(struct sip_msg* msg, char* str1, char* str2) { int result; LM_DBG("DBG:I_NDS_check_trusted: Starting ...\n"); if (msg->first_line.type!=SIP_REQUEST) { LM_ERR("ERR:I_NDS_check_trusted: The message is not a request\n"); result = CSCF_RETURN_TRUE; goto done; } if (I_NDS_is_trusted(msg,str1,str2)){ LM_DBG("INF:I_NDS_check_trusted: Message comes from a trusted domain\n"); result = CSCF_RETURN_TRUE; goto done; } else { LM_DBG("INF:I_NDS_check_trusted: Message comes from an untrusted domain\n"); result = CSCF_RETURN_FALSE; if (msg->first_line.u.request.method.len==8 && memcmp(msg->first_line.u.request.method.s,"REGISTER",8)==0){ slb.sreply(msg,403,&str_msg_403); LM_DBG("INF:I_NDS_check_trusted: REGISTER request terminated.\n"); } else { if (!I_NDS_strip_headers(msg,str1,str2)){ result = CSCF_RETURN_ERROR; slb.sreply(msg,500,&str_msg_500); LM_DBG("INF:I_NDS_check_trusted: Stripping untrusted headers failed, Responding with 500.\n"); } } } done: LM_DBG("DBG:I_NDS_check_trusted: ... Done\n"); return result; }
static int auth_send_reply(struct sip_msg *msg, int code, char *reason, char *hdr, int hdr_len) { str reason_str; /* Add new headers if there are any */ if ((hdr!=NULL) && (hdr_len>0)) { if (add_lump_rpl(msg, hdr, hdr_len, LUMP_RPL_HDR)==0) { LM_ERR("failed to append hdr to reply\n"); return -1; } } reason_str.s = reason; reason_str.len = strlen(reason); return force_stateless_reply ? slb.sreply(msg, code, &reason_str) : slb.freply(msg, code, &reason_str); }
static int xcaps_send_reply(sip_msg_t *msg, int code, str *reason, str *hdrs, str *ctype, str *body) { str tbuf; if(hdrs && hdrs->len>0) { if (add_lump_rpl(msg, hdrs->s, hdrs->len, LUMP_RPL_HDR) == 0) { LM_ERR("failed to insert extra-headers lump\n"); return -1; } } if(ctype && ctype->len>0) { /* add content-type */ tbuf.len=sizeof("Content-Type: ") - 1 + ctype->len + CRLF_LEN; tbuf.s=pkg_malloc(sizeof(char)*(tbuf.len)); if (tbuf.len==0) { LM_ERR("out of pkg memory\n"); return -1; } memcpy(tbuf.s, "Content-Type: ", sizeof("Content-Type: ") - 1); memcpy(tbuf.s+sizeof("Content-Type: ") - 1, ctype->s, ctype->len); memcpy(tbuf.s+sizeof("Content-Type: ") - 1 + ctype->len, CRLF, CRLF_LEN); if (add_lump_rpl(msg, tbuf.s, tbuf.len, LUMP_RPL_HDR) == 0) { LM_ERR("failed to insert content-type lump\n"); pkg_free(tbuf.s); return -1; } pkg_free(tbuf.s); } if(body && body->len>0) { if (add_lump_rpl(msg, body->s, body->len, LUMP_RPL_BODY) < 0) { LM_ERR("Error while adding reply lump\n"); return -1; } } if (slb.freply(msg, code, reason) < 0) { LM_ERR("Error while sending reply\n"); return -1; } return 0; }
/** * Send a reply (response) to the passed in SIP request messsage with * the code and reason. If the header is not NULL (and header_len != * 0) the add the header to the reply message. * * @param request The SIP request message to build the reply from. * @param code The response code. i.e 200 * @param reason The response reason. i.e. "OK" * @param header the header block to add to the reply. * @param header_len The length of the header block. (header) * * @return 0 on success, none-zero on an error. */ static int send_response(struct sip_msg *request, int code, str *reason, char *header, int header_len) { if (slb.freply != 0) { /* Add new headers if not null or zero length */ if ((header) && (header_len)) { if (add_lump_rpl(request, header, header_len, LUMP_RPL_HDR) == 0) { /* An error with adding the lump */ LM_ERR("unable to append header.\n"); return -1; } } /* Now using the sl function, send the reply/response */ if (slb.freply(request, code, reason) < 0) { LM_ERR("Unable to sent reply.\n"); return -1; } } else { return -1; } return(0); }
/*! \brief Initialize siptrace module */ static int mod_init(void) { pv_spec_t avp_spec; sl_cbelem_t slcb; #ifdef STATISTICS /* register statistics */ if (register_module_stats(exports.name, siptrace_stats)!=0) { LM_ERR("failed to register core statistics\n"); return -1; } #endif if(register_mi_mod(exports.name, mi_cmds)!=0) { LM_ERR("failed to register MI commands\n"); return -1; } if(siptrace_init_rpc() != 0) { LM_ERR("failed to register RPC commands\n"); return -1; } if (trace_flag<0 || trace_flag>(int)MAX_FLAG) { LM_ERR("invalid trace flag %d\n", trace_flag); return -1; } trace_flag = 1<<trace_flag; trace_to_database_flag = (int*)shm_malloc(sizeof(int)); if(trace_to_database_flag==NULL) { LM_ERR("no more shm memory left\n"); return -1; } *trace_to_database_flag = trace_to_database; if(hep_version != 1 && hep_version != 2) { LM_ERR("unsupported version of HEP"); return -1; } /* Find a database module if needed */ if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) { if (db_bind_mod(&db_url, &db_funcs)) { LM_ERR("unable to bind database module\n"); return -1; } if (trace_to_database_flag && !DB_CAPABILITY(db_funcs, DB_CAP_INSERT)) { LM_ERR("database modules does not provide all functions needed" " by module\n"); return -1; } } if(hep_version != 1 && hep_version != 2) { LM_ERR("unsupported version of HEP"); return -1; } trace_on_flag = (int*)shm_malloc(sizeof(int)); if(trace_on_flag==NULL) { LM_ERR("no more shm memory left\n"); return -1; } *trace_on_flag = trace_on; xheaders_write_flag = (int*)shm_malloc(sizeof(int)); xheaders_read_flag = (int*)shm_malloc(sizeof(int)); if (!(xheaders_write_flag && xheaders_read_flag)) { LM_ERR("no more shm memory left\n"); return -1; } *xheaders_write_flag = xheaders_write; *xheaders_read_flag = xheaders_read; /* register callbacks to TM */ if (load_tm_api(&tmb)!=0) { LM_WARN("can't load tm api. Will not install tm callbacks.\n"); } else if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0, 0) <=0) { LM_ERR("can't register trace_onreq_in\n"); return -1; } /* bind the SL API */ if (sl_load_api(&slb)!=0) { LM_WARN("cannot bind to SL API. Will not install sl callbacks.\n"); } else { /* register sl callbacks */ memset(&slcb, 0, sizeof(sl_cbelem_t)); slcb.type = SLCB_REPLY_READY; slcb.cbf = trace_sl_onreply_out; if (slb.register_cb(&slcb) != 0) { LM_ERR("can't register for SLCB_REPLY_READY\n"); return -1; } if(trace_sl_acks) { slcb.type = SLCB_ACK_FILTERED; slcb.cbf = trace_sl_ack_in; if (slb.register_cb(&slcb) != 0) { LM_ERR("can't register for SLCB_ACK_FILTERED\n"); return -1; } } } if(dup_uri_str.s!=0) { dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri)); if(dup_uri==0) { LM_ERR("no more pkg memory left\n"); return -1; } memset(dup_uri, 0, sizeof(struct sip_uri)); if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) { LM_ERR("bad dup uri\n"); return -1; } } if(force_send_sock_str.s!=0) { force_send_sock_str.len = strlen(force_send_sock_str.s); force_send_sock_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri)); if(force_send_sock_uri==0) { LM_ERR("no more pkg memory left\n"); return -1; } memset(force_send_sock_uri, 0, sizeof(struct sip_uri)); if(parse_uri(force_send_sock_str.s, force_send_sock_str.len, force_send_sock_uri)<0) { LM_ERR("bad dup uri\n"); return -1; } } if(traced_user_avp_str.s && traced_user_avp_str.len > 0) { if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", traced_user_avp_str.len, traced_user_avp_str.s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp, &traced_user_avp_type)!=0) { LM_ERR("[%.*s] - invalid AVP definition\n", traced_user_avp_str.len, traced_user_avp_str.s); return -1; } } else { traced_user_avp.n = 0; traced_user_avp_type = 0; } if(trace_table_avp_str.s && trace_table_avp_str.len > 0) { if (pv_parse_spec(&trace_table_avp_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) { LM_ERR("malformed or non AVP %.*s AVP definition\n", trace_table_avp_str.len, trace_table_avp_str.s); return -1; } if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp, &trace_table_avp_type)!=0) { LM_ERR("[%.*s] - invalid AVP definition\n", trace_table_avp_str.len, trace_table_avp_str.s); return -1; } } else { trace_table_avp.n = 0; trace_table_avp_type = 0; } return 0; }
static int opt_reply(struct sip_msg* _msg, char* _foo, char* _bar) { str rpl_hf; int offset = 0; if ((_msg->REQ_METHOD != METHOD_OTHER) || (_msg->first_line.u.request.method.len != OPTIONS_LEN) || (strncasecmp(_msg->first_line.u.request.method.s, OPTIONS, OPTIONS_LEN) != 0)) { LOG(L_ERR, "options_reply(): called for non-OPTIONS request\n"); return -1; } /* FIXME: should we additionally check if ruri == server addresses ?! */ /* janakj: no, do it in the script */ if (_msg->parsed_uri.user.len != 0) { LOG(L_ERR, "options_reply(): ruri contains username\n"); return -1; } /* calculate the length and allocated the mem */ rpl_hf.len = ACPT_STR_LEN + ACPT_ENC_STR_LEN + ACPT_LAN_STR_LEN + SUPT_STR_LEN + 4 * CRLF_LEN + acpt_body.len + acpt_enc_body.len + acpt_lan_body.len + supt_body.len; rpl_hf.s = (char*)pkg_malloc(rpl_hf.len); if (!rpl_hf.s) { LOG(L_CRIT, "options_reply(): out of memory\n"); goto error; } /* create the header fields */ memcpy(rpl_hf.s, ACPT_STR, ACPT_STR_LEN); offset = ACPT_STR_LEN; memcpy(rpl_hf.s + offset, acpt_body.s, acpt_body.len); offset += acpt_body.len; memcpy(rpl_hf.s + offset, CRLF, CRLF_LEN); offset += CRLF_LEN; memcpy(rpl_hf.s + offset, ACPT_ENC_STR, ACPT_ENC_STR_LEN); offset += ACPT_ENC_STR_LEN; memcpy(rpl_hf.s + offset, acpt_enc_body.s, acpt_enc_body.len); offset += acpt_enc_body.len; memcpy(rpl_hf.s + offset, CRLF, CRLF_LEN); offset += CRLF_LEN; memcpy(rpl_hf.s + offset, ACPT_LAN_STR, ACPT_LAN_STR_LEN); offset += ACPT_LAN_STR_LEN; memcpy(rpl_hf.s + offset, acpt_lan_body.s, acpt_lan_body.len); offset += acpt_lan_body.len; memcpy(rpl_hf.s + offset, CRLF, CRLF_LEN); offset += CRLF_LEN; memcpy(rpl_hf.s + offset, SUPT_STR, SUPT_STR_LEN); offset += SUPT_STR_LEN; memcpy(rpl_hf.s + offset, supt_body.s, supt_body.len); offset += supt_body.len; memcpy(rpl_hf.s + offset, CRLF, CRLF_LEN); offset += CRLF_LEN; #ifdef EXTRA_DEBUG if (offset != rpl_hf.len) { LOG(L_CRIT, "options_reply(): headerlength (%i) != offset (%i)\n", rpl_hf.len, offset); abort(); } #endif if (add_lump_rpl( _msg, rpl_hf.s, rpl_hf.len, LUMP_RPL_HDR|LUMP_RPL_NODUP)!=0) { if (sl.reply(_msg, 200, "OK") == -1) { LOG(L_ERR, "options_reply(): failed to send 200 via send_reply\n"); return -1; } else { return 0; } } else { pkg_free(rpl_hf.s); LOG(L_ERR, "options_reply(): add_lump_rpl failed\n"); } error: if (sl.reply(_msg, 500, "Server internal error") == -1) { LOG(L_ERR, "options_reply(): failed to send 500 via send_reply\n"); return -1; } else { return 0; } }