/* * find client domain * return 0 if virtual domain not found */ struct tls_domain *tls_find_client_domain(struct ip_addr *ip, unsigned short port) { struct tls_domain *dom; struct usr_avp *avp; int_str val; avp = NULL; if (tls_client_domain_avp > 0) avp = search_first_avp(0, tls_client_domain_avp, &val, 0); else LM_DBG("name based TLS client domain matching is disabled\n"); if (dom_lock) lock_start_read(dom_lock); if (!avp) { LM_DBG("no TLS client domain AVP set, looking " "to match TLS client domain by scoket\n"); dom = tls_find_client_domain_addr(ip, port); if (dom) { LM_DBG("found TLS client domain [%s:%d] based on socket\n", ip_addr2a(&dom->addr), dom->port); } } else { LM_DBG("TLS client domain AVP found = '%.*s'\n", val.s.len, ZSW(val.s.s)); dom = tls_find_client_domain_name(val.s); if (dom) { LM_DBG("found TLS client domain '%.*s' by name\n", val.s.len, ZSW(val.s.s)); } else { LM_DBG("TLS client domain not found by name, " "trying socket based TLS client domain matching\n"); dom = tls_find_client_domain_addr(ip, port); if (dom) { LM_DBG("found TLS client domain [%s:%d] based on socket\n", ip_addr2a(&dom->addr), dom->port); } } } if (dom && dom->type & TLS_DOMAIN_DB) { lock_get(dom->lock); dom->refs++; lock_release(dom->lock); } if (dom_lock) lock_stop_read(dom_lock); return dom; }
/** wrapper around SSL_connect, using SSL return convention. * It will also log critical errors and certificate debugging info. * @param c - tcp connection with tls (extra_data must be a filled * tcp_extra_data structure). The state must be S_TLS_CONNECTING. * @param error set to the error reason (SSL_ERROR_*). * Note that it can be SSL_ERROR_NONE while the return is < 0 * ("internal" error, not at the SSL level, see below). * @return >=1 on success, 0 and <0 on error. 0 means the underlying SSL * connection was closed/shutdown. < 0 is returned for any * SSL_ERROR (including WANT_READ or WANT_WRITE), but also * for internal non SSL related errors (in this case -2 is * returned and error==SSL_ERROR_NONE). * */ int tls_connect(struct tcp_connection *c, int* error) { SSL *ssl; int ret; X509* cert; struct tls_extra_data* tls_c; int tls_log; *error = SSL_ERROR_NONE; tls_c=(struct tls_extra_data*)c->extra_data; ssl=tls_c->ssl; if (unlikely(tls_c->state != S_TLS_CONNECTING)) { BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state); goto err; } ret = SSL_connect(ssl); if (unlikely(ret == 1)) { DBG("TLS connect successful\n"); tls_c->state = S_TLS_ESTABLISHED; tls_log = cfg_get(tls, tls_cfg, log); LOG(tls_log, "tls_connect: new connection to %s:%d using %s %s %d\n", ip_addr2a(&c->rcv.src_ip), c->rcv.src_port, SSL_get_cipher_version(ssl), SSL_get_cipher_name(ssl), SSL_get_cipher_bits(ssl, 0) ); LOG(tls_log, "tls_connect: sending socket: %s:%d \n", ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port ); cert = SSL_get_peer_certificate(ssl); if (cert != 0) { tls_dump_cert_info("tls_connect: server certificate", cert); if (SSL_get_verify_result(ssl) != X509_V_OK) { LOG(tls_log, "WARNING: tls_connect: server certificate " "verification failed!!!\n"); tls_dump_verification_failure(SSL_get_verify_result(ssl)); } X509_free(cert); } else { /* this should not happen, servers always present a cert */ LOG(tls_log, "tls_connect: server did not " "present a certificate\n"); } tls_run_event_routes(c); } else { /* 0 or < 0 */ *error = SSL_get_error(ssl, ret); } return ret; err: /* internal non openssl related errors */ return -2; }
/** wrapper around SSL_accept, usin SSL return convention. * It will also log critical errors and certificate debugging info. * @param c - tcp connection with tls (extra_data must be a filled * tcp_extra_data structure). The state must be S_TLS_ACCEPTING. * @param error set to the error reason (SSL_ERROR_*). * Note that it can be SSL_ERROR_NONE while the return is < 0 * ("internal" error, not at the SSL level, see below). * @return >=1 on success, 0 and <0 on error. 0 means the underlying SSL * connection was closed/shutdown. < 0 is returned for any * SSL_ERROR (including WANT_READ or WANT_WRITE), but also * for internal non SSL related errors (in this case -2 is * returned and error==SSL_ERROR_NONE). * */ int tls_accept(struct tcp_connection *c, int* error) { int ret; SSL *ssl; X509* cert; struct tls_extra_data* tls_c; int tls_log; *error = SSL_ERROR_NONE; tls_c=(struct tls_extra_data*)c->extra_data; ssl=tls_c->ssl; if (unlikely(tls_c->state != S_TLS_ACCEPTING)) { BUG("Invalid connection state %d (bug in TLS code)\n", tls_c->state); goto err; } ret = SSL_accept(ssl); if (unlikely(ret == 1)) { DBG("TLS accept successful\n"); tls_c->state = S_TLS_ESTABLISHED; tls_log = cfg_get(tls, tls_cfg, log); LOG(tls_log, "tls_accept: new connection from %s:%d using %s %s %d\n", ip_addr2a(&c->rcv.src_ip), c->rcv.src_port, SSL_get_cipher_version(ssl), SSL_get_cipher_name(ssl), SSL_get_cipher_bits(ssl, 0) ); LOG(tls_log, "tls_accept: local socket: %s:%d\n", ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port ); cert = SSL_get_peer_certificate(ssl); if (cert != 0) { tls_dump_cert_info("tls_accept: client certificate", cert); if (SSL_get_verify_result(ssl) != X509_V_OK) { LOG(tls_log, "WARNING: tls_accept: client certificate " "verification failed!!!\n"); tls_dump_verification_failure(SSL_get_verify_result(ssl)); } X509_free(cert); } else { LOG(tls_log, "tls_accept: client did not present a certificate\n"); } } else { /* ret == 0 or < 0 */ *error = SSL_get_error(ssl, ret); } return ret; err: /* internal non openssl related errors */ return -2; }
/* get provider pointer from emergency service provider table * get 3 types of provider, depend on its attribution: * 0 - source provider * 1 - VPC provider * 2 - vsp provider */ struct service_provider* get_provider(struct sip_msg *msg, int attr, rw_lock_t *ref_lock ) { int vsp_addr_len; char *vsp_addr; lock_start_read(ref_lock); struct service_provider* provider = *db_service_provider; while (provider != NULL) { LM_DBG("***attr:%d\n ", provider->attribution); if (provider->attribution == attr ){ if (provider->attribution == 2){ // search ip source vsp_addr = ip_addr2a(&msg->rcv.src_ip); vsp_addr_len = strlen(vsp_addr); if ( (provider->nodeIP.len == vsp_addr_len) && (strncmp(vsp_addr, provider->nodeIP.s, vsp_addr_len) == 0)) { LM_DBG(" FOUND IP SOURCE\n "); lock_stop_read(ref_lock); return provider; } }else{ lock_stop_read(ref_lock); return provider; } } provider = provider->next; } lock_stop_read(ref_lock); return NULL; }
/* only for debugging, it helds the lock too long for "production" use */ void dst_blst_debug(rpc_t* rpc, void* ctx) { int h; struct dst_blst_entry* e; ticks_t now; struct ip_addr ip; if (!cfg_get(core, core_cfg, use_dst_blacklist)){ rpc->fault(ctx, 500, "dst blacklist support disabled"); return; } now=get_ticks_raw(); for(h=0; h<DST_BLST_HASH_SIZE; h++){ LOCK_BLST(h); for(e=dst_blst_hash[h].first; e; e=e->next){ dst_blst_entry2ip(&ip, e); rpc->add(ctx, "ssddd", get_proto_name(e->proto), ip_addr2a(&ip), e->port, (s_ticks_t)(now-e->expire)<=0? TICKS_TO_S(e->expire-now): -TICKS_TO_S(now-e->expire) , e->flags); } UNLOCK_BLST(h); } }
/* dumps the content of the blacklist in a human-readable format */ void dst_blst_view(rpc_t* rpc, void* ctx) { int h; int expires; struct dst_blst_entry* e; ticks_t now; struct ip_addr ip; if (!cfg_get(core, core_cfg, use_dst_blacklist)){ rpc->fault(ctx, 500, "dst blacklist support disabled"); return; } now=get_ticks_raw(); for(h=0; h<DST_BLST_HASH_SIZE; h++) { LOCK_BLST(h); for(e=dst_blst_hash[h].first; e; e=e->next) { expires = (s_ticks_t)(now-e->expire)<=0? TICKS_TO_S(e->expire-now): -TICKS_TO_S(now-e->expire); /* don't include expired entries into view report */ if (expires < 0) { continue; } dst_blst_entry2ip(&ip, e); rpc->printf(ctx, "{\n protocol: %s", get_proto_name(e->proto)); rpc->printf(ctx, " ip: %s", ip_addr2a(&ip)); rpc->printf(ctx, " port: %d", e->port); rpc->printf(ctx, " expires in (s): %d", expires); rpc->printf(ctx, " flags: %d\n}", e->flags); } UNLOCK_BLST(h); } }
/** * Checks if the sent-by parameter in the first Via header equals the source IP address of the message * @param req - the SIP request * @param str1 - not used * @param str2 - not used * @returns true if ok, false if not or error */ int P_check_via_sent_by(struct sip_msg *msg,char *str1, char *str2) { int ret = CSCF_RETURN_FALSE; struct ip_addr *src_ip; char *src_ip_ch; str sent_by={0,0}; /* get the real receive IP address */ src_ip = &(msg->rcv.src_ip); src_ip_ch = ip_addr2a(src_ip); LOG(L_DBG,"DBG:"M_NAME":P_check_sent_by(): Received from <%s>\n",src_ip_ch); /* find the sent-by Via parameter */ sent_by = cscf_get_last_via_sent_by(msg); LOG(L_DBG,"DBG:"M_NAME":P_check_sent_by(): Via sent-by=<%.*s>\n",sent_by.len,sent_by.s); /* if not found, exit now */ if (sent_by.len == 0) { LOG(L_DBG,"DBG:"M_NAME":P_check_sent_by(): Via does not contain a sent-by value\n"); return ret; } /* if found, check if it is matching */ if (sent_by.len==strlen(src_ip_ch) && strncasecmp(sent_by.s,src_ip_ch,sent_by.len)==0){ ret = CSCF_RETURN_TRUE; LOG(L_DBG,"DBG:"M_NAME":P_check_sent_by(): sent-by matches the actual IP received from\n"); }else{ ret = CSCF_RETURN_FALSE; LOG(L_DBG,"DBG:"M_NAME":P_check_sent_by(): sent-by does not match the actual IP received from\n"); } return ret; }
void rtpproxy_pre_fwd(struct sip_msg *msg, cb_type_t cb_type, void *mod_args, void *core_args) { struct proxy_l *p; struct ip_addr ip; char *cp; struct force_rtpp_args *args; assert(cb_type == REQ_PRE_FORWARD); p = (struct proxy_l *)core_args; args = (struct force_rtpp_args *)mod_args; if (args->raddr.s != NULL) return; hostent2ip_addr(&ip, &p->host, p->addr_idx); cp = ip_addr2a(&ip); args->raddr.len = strlen(cp); if (ip.af == AF_INET) { args->raddr.s = pkg_malloc(args->raddr.len + 1); if (args->raddr.s == NULL) { LM_ERR("out of pkg memory\n"); return; } sprintf(args->raddr.s, "%s", cp); } else { args->raddr.len += 2; args->raddr.s = pkg_malloc(args->raddr.len + 1); if (args->raddr.s == NULL) { LM_ERR("out of pkg memory\n"); return; } sprintf(args->raddr.s, "[%s]", cp); } force_rtp_proxy_body(msg, args, NULL, NULL); }
int create_via(struct sip_msg* msg, char* s1, char* s2) { char* via; unsigned int via_len; str ip, port; struct hostport hp; struct dest_info dst; ip.s = ip_addr2a(&msg->rcv.src_ip); ip.len = strlen(ip.s); port.s = int2str(msg->rcv.src_port, &port.len); hp.host = &ip; hp.port = &port; init_dst_from_rcv(&dst, &msg->rcv); via = via_builder(&via_len, &dst, 0, 0, &hp); if (!via) { ERR("Unable to build Via header field\n"); return -1; } if (insert_fake_via(msg, via, via_len) < 0) { pkg_free(via); return -1; } if (insert_via_lump(msg, via, via_len - CRLF_LEN) < 0) { pkg_free(via); return -1; } return 1; }
static PyObject * msg_get_dst_address(msgobject *self, PyObject *unused) { PyObject *dst_ip, *dst_port, *pyRval; if (self->msg == NULL) { PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL"); Py_INCREF(Py_None); return Py_None; } dst_ip = PyString_FromString(ip_addr2a(&self->msg->rcv.dst_ip)); if (dst_ip == NULL) { Py_INCREF(Py_None); return Py_None; } dst_port = PyInt_FromLong(self->msg->rcv.dst_port); if (dst_port == NULL) { Py_DECREF(dst_ip); Py_INCREF(Py_None); return Py_None; } pyRval = PyTuple_Pack(2, dst_ip, dst_port); Py_DECREF(dst_ip); Py_DECREF(dst_port); if (pyRval == NULL) { Py_INCREF(Py_None); return Py_None; } return pyRval; }
/* * Replaces ip:port pair in the Contact: field with the source address * of the packet and/or adds direction=active option to the SDP. */ static int fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2) { int offset, len, len1; char *cp, *buf, temp[2]; contact_t* c; struct lump* anchor; struct sip_uri uri; if ((parse_headers(msg, HDR_CONTACT, 0) == -1) || !msg->contact) return -1; if (!msg->contact->parsed && parse_contact(msg->contact) < 0) { LOG(L_ERR, "fix_nated_contact: Error while parsing Contact body\n"); return -1; } c = ((contact_body_t*)msg->contact->parsed)->contacts; if (!c) { LOG(L_ERR, "fix_nated_contact: Error while parsing Contact body\n"); return -1; } if (parse_uri(c->uri.s, c->uri.len, &uri) < 0 || uri.host.len <= 0) { LOG(L_ERR, "fix_nated_contact: Error while parsing Contact URI\n"); return -1; } if (uri.proto != PROTO_UDP && uri.proto != PROTO_NONE) return 0; if (uri.port.len == 0) uri.port.s = uri.host.s + uri.host.len; offset = c->uri.s - msg->buf; anchor = del_lump(&msg->add_rm, offset, c->uri.len, HDR_CONTACT); if (anchor == 0) return -1; cp = ip_addr2a(&msg->rcv.src_ip); len = c->uri.len + strlen(cp) + 6 /* :port */ - (uri.port.s + uri.port.len - uri.host.s) + 1; buf = pkg_malloc(len); if (buf == NULL) { LOG(L_ERR, "ERROR: fix_nated_contact: out of memory\n"); return -1; } temp[0] = uri.host.s[0]; temp[1] = c->uri.s[c->uri.len]; c->uri.s[c->uri.len] = uri.host.s[0] = '\0'; len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp, msg->rcv.src_port, uri.port.s + uri.port.len); if (len1 < len) len = len1; uri.host.s[0] = temp[0]; c->uri.s[c->uri.len] = temp[1]; if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT) == 0) { pkg_free(buf); return -1; } c->uri.s = buf; c->uri.len = len; return 1; }
int ops_write_avp(struct sip_msg* msg, struct fis_param *src, struct fis_param *ap) { struct sip_uri uri; int_str avp_val; unsigned short flags; str s_ip; if (src->flags&AVPOPS_VAL_NONE) { if (src->flags&AVPOPS_USE_SRC_IP) { /* get data from src_ip */ if ( (s_ip.s=ip_addr2a( &msg->rcv.src_ip ))==0) { LOG(L_ERR,"ERROR:avpops:write_avp: cannot get src_ip\n"); goto error; } s_ip.len = strlen(s_ip.s); avp_val.s = &s_ip; } else { /* get data from uri (from,to,ruri) */ if (src->flags&(AVPOPS_FLAG_USER|AVPOPS_FLAG_DOMAIN)) { if (parse_source_uri( msg, src->flags, &uri)!=0 ) { LOG(L_ERR,"ERROR:avpops:write_avp: cannot parse uri\n"); goto error; } if (src->flags&AVPOPS_FLAG_DOMAIN) avp_val.s = &uri.host; else avp_val.s = &uri.user; } else { /* get whole uri */ if ( (avp_val.s=get_source_uri(msg,src->flags))==0 ) { LOG(L_ERR,"ERROR:avpops:write_avp: cannot get uri\n"); goto error; } } } flags = AVP_VAL_STR; } else { avp_val = src->val; flags = (src->flags&AVPOPS_VAL_INT)?0:AVP_VAL_STR; } /* set the proper flag */ flags |= (ap->flags&AVPOPS_VAL_INT)?0:AVP_NAME_STR; /* added the avp */ if (add_avp( flags, ap->val, avp_val)<0) goto error; return 1; error: return -1; }
/* * Replaces ip:port pair in the Contact: field with the source address * of the packet. */ static int fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2) { int offset, len, len1; char *cp, *buf, temp[2]; contact_t *c; struct lump *anchor; struct sip_uri uri; str hostport; if (get_contact_uri(msg, &uri, &c) == -1) return -1; /* for UAs behind NAT we have to hope that they will reuse the * TCP connection, otherwise they are lost any way. So this check * does not make too much sense. if (uri.proto != PROTO_UDP && uri.proto != PROTO_NONE) return -1; */ if ((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) { LOG(L_ERR, "ERROR: you can't call fix_nated_contact twice, " "check your config!\n"); return -1; } offset = c->uri.s - msg->buf; anchor = del_lump(msg, offset, c->uri.len, HDR_CONTACT_T); if (anchor == 0) return -1; hostport = uri.host; if (uri.port.len > 0) hostport.len = uri.port.s + uri.port.len - uri.host.s; cp = ip_addr2a(&msg->rcv.src_ip); len = c->uri.len + strlen(cp) + 6 /* :port */ - hostport.len + 1; buf = pkg_malloc(len); if (buf == NULL) { LOG(L_ERR, "ERROR: fix_nated_contact: out of memory\n"); return -1; } temp[0] = hostport.s[0]; temp[1] = c->uri.s[c->uri.len]; c->uri.s[c->uri.len] = hostport.s[0] = '\0'; len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp, msg->rcv.src_port, hostport.s + hostport.len); if (len1 < len) len = len1; hostport.s[0] = temp[0]; c->uri.s[c->uri.len] = temp[1]; if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT_T) == 0) { pkg_free(buf); return -1; } c->uri.s = buf; c->uri.len = len; return 1; }
/* * process_stun_msg(): * buf - incoming message * len - length of incoming message * ri - information about socket that received a message and * also information about sender (its IP, port, protocol) * * This function ensures processing of incoming message. It's common for both * TCP and UDP protocol. There is no other function as an interface. * * Return value: 0 if there is no environment error * -1 if there is some enviroment error such as insufficiency * of memory * */ int process_stun_msg(char* buf, unsigned len, struct receive_info* ri) { struct stun_msg msg_req; struct stun_msg msg_res; struct dest_info dst; struct stun_unknown_att* unknown; USHORT_T error_code; memset(&msg_req, 0, sizeof(msg_req)); memset(&msg_res, 0, sizeof(msg_res)); msg_req.msg.buf.s = buf; msg_req.msg.buf.len = len; unknown = NULL; error_code = RESPONSE_OK; if (stun_parse_header(&msg_req, &error_code) != 0) { goto error; } if (error_code == RESPONSE_OK) { if (stun_parse_body(&msg_req, &unknown, &error_code) != 0) { goto error; } } if (stun_create_response(&msg_req, &msg_res, ri, unknown, error_code) != 0) { goto error; } init_dst_from_rcv(&dst, ri); #ifdef EXTRA_DEBUG struct ip_addr ip; su2ip_addr(&ip, &dst.to); LOG(L_DBG, "DEBUG: process_stun_msg: decoded request from (%s:%d)\n", ip_addr2a(&ip), su_getport(&dst.to)); #endif /* send STUN response */ if (msg_send(&dst, msg_res.msg.buf.s, msg_res.msg.buf.len) != 0) { goto error; } #ifdef EXTRA_DEBUG LOG(L_DBG, "DEBUG: process_stun_msg: send response\n"); #endif clean_memory(&msg_req, &msg_res, unknown); return 0; error: #ifdef EXTRA_DEBUG LOG(L_DBG, "DEBUG: process_stun_msg: failed to decode request\n"); #endif clean_memory(&msg_req, &msg_res, unknown); return FATAL_ERROR; }
int proto_sctp_read(struct socket_info *si, int* bytes_read) { struct receive_info ri; int len; #ifdef DYN_BUF char* buf; #else static char buf [BUF_SIZE+1]; #endif char *tmp; unsigned int fromlen; struct sctp_sndrcvinfo sinfo; #ifdef DYN_BUF buf=pkg_malloc(BUF_SIZE+1); if (buf==0) { LM_ERR(" could not allocate receive buffer in pkg memory\n"); goto error; } #endif fromlen=sockaddru_len(si->su); len = sctp_recvmsg(si->socket, buf, BUF_SIZE, &ri.src_su.s, &fromlen, &sinfo, 0); if (len==-1) { if (errno==EAGAIN) { LM_DBG("packet with bad checksum received\n"); return 0; } if ((errno==EINTR)||(errno==EWOULDBLOCK)|| (errno==ECONNREFUSED)) return -1; LM_ERR("sctp_recvmsg:[%d] %s\n", errno, strerror(errno)); return -2; } /* we must 0-term the messages, receive_msg expects it */ buf[len]=0; /* no need to save the previous char */ ri.bind_address = si; ri.dst_port = si->port_no; ri.dst_ip = si->address; ri.proto = si->proto; ri.proto_reserved1 = ri.proto_reserved2 = 0; su2ip_addr(&ri.src_ip, &ri.src_su); ri.src_port=su_getport(&ri.src_su); if (ri.src_port==0) { tmp=ip_addr2a(&ri.src_ip); LM_INFO("dropping 0 port packet from %s\n", tmp); return 0; } /* receive_msg must free buf too!*/ receive_msg(buf, len, &ri); return 0; }
/** * Adds a received parameter to the first via with the source IP of the message. * @param req - the SIP request * @param str1 - not used * @param str2 - not used * @returns true if ok, false if not or error */ int P_add_via_received(struct sip_msg *msg,char *str1, char *str2) { struct via_body *via; struct via_param *vp; str received={0,0}; struct ip_addr *src_ip; char *src_ip_ch; int len; struct lump* anchor,*l; char *x; /* first add a received parameter */ via = msg->via1; /* if we already have a received header, SER will take care of it and put the right value */ if (via->received) goto delete_others; x = via->port_str.s+via->port_str.len; if (!x) x= via->host.s+via->host.len; anchor = anchor_lump(msg, x-msg->buf, 0 , 0 ); if (anchor == NULL) { LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): anchor_lump failed\n"); return 0; } src_ip = &(msg->rcv.src_ip); src_ip_ch = ip_addr2a(src_ip); len = strlen(src_ip_ch); received.len = s_received.len+len; received.s = pkg_malloc(received.len); if (!received.s){ LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): allocating %d bytes\n",received.len); return CSCF_RETURN_ERROR; } memcpy(received.s,s_received.s,s_received.len); memcpy(received.s+s_received.len,src_ip_ch,len); if (!(l=insert_new_lump_before(anchor, received.s,received.len,0))){ LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): error creating lump for received parameter\n" ); return CSCF_RETURN_ERROR; } /* then remove the old received params*/ delete_others: for(vp = via->param_lst; vp; vp = vp->next) if (vp->name.len == s_received2.len && strncasecmp(vp->name.s,s_received2.s,s_received2.len)==0){ LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): Found old received parameter!! This might indicate an attack.\n" ); if (!del_lump(msg,vp->start-msg->buf-1,vp->size+1,0)){ LOG(L_ERR,"ERR:"M_NAME":P_add_via_received(): Error deleting old received parameter from first via\n"); return CSCF_RETURN_ERROR; } } return CSCF_RETURN_TRUE; }
static int xl_get_srcip(struct sip_msg *msg, str *res) { if(msg==NULL || res==NULL) return -1; res->s = ip_addr2a(&msg->rcv.src_ip); res->len = strlen(res->s); return 0; }
static int sel_rewrite_contact(str* res, select_t* s, struct sip_msg* msg) { static char buf[500]; contact_t* c; int n, def_port_fl, len; char *cp; str hostport; struct sip_uri uri; res->len = 0; n = s->params[2].v.i; if (n <= 0) { LOG(L_ERR, "ERROR: rewrite_contact[%d]: zero or negative index not supported\n", n); return -1; } c = 0; do { if (contact_iterator(&c, msg, c) < 0 || !c) return -1; n--; } while (n > 0); if (parse_uri(c->uri.s, c->uri.len, &uri) < 0 || uri.host.len <= 0) { LOG(L_ERR, "rewrite_contact[%d]: Error while parsing Contact URI\n", s->params[2].v.i); return -1; } len = c->len - uri.host.len; if (uri.port.len > 0) len -= uri.port.len; def_port_fl = (msg->rcv.proto == PROTO_TLS && msg->rcv.src_port == SIPS_PORT) || (msg->rcv.proto != PROTO_TLS && msg->rcv.src_port == SIP_PORT); if (!def_port_fl) len += 1/*:*/+5/*port*/; if (len > sizeof(buf)) { LOG(L_ERR, "ERROR: rewrite_contact[%d]: contact too long\n", s->params[2].v.i); return -1; } hostport = uri.host; if (uri.port.len > 0) hostport.len = uri.port.s + uri.port.len - uri.host.s; res->s = buf; res->len = hostport.s - c->name.s; memcpy(buf, c->name.s, res->len); cp = ip_addr2a(&msg->rcv.src_ip); if (def_port_fl) { res->len+= snprintf(buf+res->len, sizeof(buf)-res->len, "%s", cp); } else { res->len+= snprintf(buf+res->len, sizeof(buf)-res->len, "%s:%d", cp, msg->rcv.src_port); } memcpy(buf+res->len, hostport.s+hostport.len, c->len-(hostport.s+hostport.len-c->name.s)); res->len+= c->len-(hostport.s+hostport.len-c->name.s); return 0; }
/* * Wrapper around SSL_read * * returns number of bytes read, 0 on eof and transits into S_CONN_EOF, -1 * on error */ static int _tls_read(struct tcp_connection *c, void *buf, size_t len) { int ret, err; SSL *ssl; ssl = c->extra_data; ret = SSL_read(ssl, buf, len); if (ret > 0) { LM_DBG("%d bytes read\n", ret); return ret; } else { err = SSL_get_error(ssl, ret); switch (err) { case SSL_ERROR_ZERO_RETURN: LM_DBG("TLS connection to %s:%d closed cleanly\n", ip_addr2a(&c->rcv.src_ip), c->rcv.src_port); /* * mark end of file */ c->state = S_CONN_EOF; return 0; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: return 0; case SSL_ERROR_SYSCALL: LM_ERR("SYSCALL error -> (%d) <%s>\n",errno,strerror(errno)); default: LM_ERR("TLS connection to %s:%d read failed\n", ip_addr2a(&c->rcv.src_ip), c->rcv.src_port); LM_ERR("TLS read error: %d\n",err); c->state = S_CONN_BAD; tls_print_errstack(); return -1; } } LM_BUG("bug\n"); return -1; }
int siptrace_net_data_recv(void *data) { sr_net_info_t *nd; struct _siptrace_data sto; if(data==0) return -1; nd = (sr_net_info_t*)data; if(nd->rcv==NULL || nd->data.s==NULL || nd->data.len<=0) return -1; memset(&sto, 0, sizeof(struct _siptrace_data)); sto.body.s = nd->data.s; sto.body.len = nd->data.len; siptrace_copy_proto(nd->rcv->proto, sto.fromip_buff); strcat(sto.fromip_buff, ip_addr2a(&nd->rcv->src_ip)); strcat(sto.fromip_buff,":"); strcat(sto.fromip_buff, int2str(nd->rcv->src_port, NULL)); sto.fromip.s = sto.fromip_buff; sto.fromip.len = strlen(sto.fromip_buff); siptrace_copy_proto(nd->rcv->proto, sto.toip_buff); strcat(sto.toip_buff, ip_addr2a(&nd->rcv->dst_ip)); strcat(sto.toip_buff,":"); strcat(sto.toip_buff, int2str(nd->rcv->dst_port, NULL)); sto.toip.s = sto.toip_buff; sto.toip.len = strlen(sto.toip_buff); sto.dir = "in"; trace_send_hep_duplicate(&sto.body, &sto.fromip, &sto.toip, NULL); return 0; }
/* * Check if an entry exists in hash table that has given src_ip and protocol * value and pattern that matches to From URI. If, assign */ int match_hash_table(struct trusted_list** table, struct sip_msg* msg) { str uri; char uri_string[MAX_URI_SIZE + 1]; regex_t preg; struct trusted_list *np; str src_ip; int_str val; src_ip.s = ip_addr2a(&msg->rcv.src_ip); src_ip.len = strlen(src_ip.s); if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LM_ERR("from URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) { if ((np->src_ip.len == src_ip.len) && (strncasecmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) && ((np->proto == PROTO_NONE) || (np->proto == msg->rcv.proto))) { if (!(np->pattern)) goto found; if (regcomp(&preg, np->pattern, REG_NOSUB)) { LM_ERR("invalid regular expression\n"); return -1; } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); } else { regfree(&preg); goto found; } } } return -1; found: if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return 1; }
// Get caller signaling IP static str get_signaling_ip(struct sip_msg* msg) { int_str value; if (!search_first_avp(signaling_ip_avp.type | AVP_VAL_STR, signaling_ip_avp.name, &value, NULL) || !value.s.s || value.s.len==0) { value.s.s = ip_addr2a(&msg->rcv.src_ip); value.s.len = strlen(value.s.s); } return value.s; }
void init_acc_extra(void) { int i; /* ugly trick to get the address of the static buffer */ static_detector[0] = int2str( (unsigned long)3, &i) + i; if (udp_listen) { static_detector[1] = ip_addr2a(&udp_listen->address); #ifdef USE_TCP } else if (tcp_listen) { static_detector[1] = ip_addr2a(&tcp_listen->address); #endif #ifdef USE_TLS } else if (tls_listen) { static_detector[1] = ip_addr2a(&tls_listen->address); #endif #ifdef USE_SCTP } else if (sctp_listen) { static_detector[1] = ip_addr2a(&sctp_listen->address); #endif } else { LM_CRIT("BUG - no listen interface found!!\n"); static_detector[1] = NULL; } }
static char* xhttp_to_sip(sip_msg_t* msg, int* new_msg_len) { unsigned int len, via_len; char* via, *new_msg, *p; str ip, port; struct hostport hp; struct dest_info dst; ip.s = ip_addr2a(&msg->rcv.src_ip); ip.len = strlen(ip.s); port.s = int2str(msg->rcv.src_port, &port.len); hp.host = &ip; hp.port = &port; init_dst_from_rcv(&dst, &msg->rcv); via = via_builder(&via_len, &dst, 0, 0, &hp); if (via == 0) { LM_DBG("failed to build via\n"); return 0; } len = via_len + msg->len; p = new_msg = pkg_malloc(len + 1); if (new_msg == 0) { LM_DBG("memory allocation failure (%d bytes)\n", len); pkg_free(via); return 0; } /* new message: * <orig first line> * Via: <faked via> * <orig http message w/o the first line> */ memcpy(p, msg->first_line.u.request.method.s, msg->first_line.len); p += msg->first_line.len; memcpy(p, via, via_len); p += via_len; memcpy(p, SIP_MSG_START(msg) + msg->first_line.len, msg->len - msg->first_line.len); new_msg[len] = 0; pkg_free(via); *new_msg_len = len; return new_msg; }
/* * Print subnets stored in subnet table */ int subnet_table_mi_print(struct subnet* table, struct mi_node* rpl) { unsigned int count, i; count = table[PERM_MAX_SUBNETS].grp; for (i = 0; i < count; i++) { if (addf_mi_node_child(rpl, 0, 0, 0, "%4d <%u, %s, %u, %u> [%s]", i, table[i].grp, ip_addr2a(&table[i].subnet), table[i].mask, table[i].port, (table[i].tag.s==NULL)?"":table[i].tag.s) == 0) { return -1; } } return 0; }
/* * Wrapper around SSL_write, returns number of bytes written on success, * * -1 on error, 0 when it would block */ static int tls_write(struct tcp_connection *c, int fd, const void *buf, size_t len, short *poll_events) { int ret, err; /* * runs within write lock, no need to lock here */ SSL *ssl; ssl = (SSL *) c->extra_data; ret = SSL_write(ssl, buf, len); if (ret > 0) { LM_DBG("write was successful (%d bytes)\n", ret); return ret; } else { err = SSL_get_error(ssl, ret); switch (err) { case SSL_ERROR_ZERO_RETURN: LM_DBG("connection closed cleanly\n"); c->state = S_CONN_EOF; return -1; case SSL_ERROR_WANT_READ: if (poll_events) *poll_events = POLLIN; return 0; case SSL_ERROR_WANT_WRITE: if (poll_events) *poll_events = POLLOUT; return 0; default: LM_ERR("TLS connection to %s:%d write failed\n", ip_addr2a(&c->rcv.src_ip), c->rcv.src_port); LM_ERR("TLS write error:\n"); c->state = S_CONN_BAD; tls_print_errstack(); return -1; } } LM_ERR("bug\n"); return -1; }
/** * @brief Generate TLS domain identifier * @param d printed domain * @return printed domain, with zero termination */ char* tls_domain_str(tls_domain_t* d) { static char buf[1024]; char* p; buf[0] = '\0'; p = buf; p = strcat(p, d->type & TLS_DOMAIN_SRV ? "TLSs<" : "TLSc<"); if (d->type & TLS_DOMAIN_DEF) { p = strcat(p, "default>"); } else { p = strcat(p, ip_addr2a(&d->ip)); p = strcat(p, ":"); p = strcat(p, int2str(d->port, 0)); p = strcat(p, ">"); } return buf; }
/*! \brief * MI: Print addresses stored in hash table */ int addr_hash_table_mi_print(struct addr_list** table, struct mi_node* rpl) { int i; struct addr_list *np; for (i = 0; i < PERM_HASH_SIZE; i++) { np = table[i]; while (np) { if (addf_mi_node_child(rpl, 0, 0, 0, "%4d <%u, %s, %u> [%s]", i, np->grp, ip_addr2a(&np->addr), np->port, (np->tag.s==NULL)?"":np->tag.s) == 0) return -1; np = np->next; } } return 0; }
int pv_get_sndto(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { struct onsend_info* snd_inf; struct ip_addr ip; str s; snd_inf=get_onsend_info(); if (! likely(snd_inf && snd_inf->send_sock)) return pv_get_null(msg, param, res); switch(param->pvn.u.isname.name.n) { case 1: /* af */ return pv_get_uintval(msg, param, res, (int)snd_inf->send_sock->address.af); case 2: /* port */ return pv_get_uintval(msg, param, res, (int)su_getport(snd_inf->to)); case 3: /* proto */ return pv_get_uintval(msg, param, res, (int)snd_inf->send_sock->proto); case 4: /* buf */ s.s = snd_inf->buf; s.len = snd_inf->len; return pv_get_strval(msg, param, res, &s); case 5: /* len */ return pv_get_uintval(msg, param, res, (int)snd_inf->len); case 6: /* sproto */ if(get_valid_proto_string((int)snd_inf->send_sock->proto, 0, 0, &s)<0) return pv_get_null(msg, param, res); return pv_get_strval(msg, param, res, &s); default: /* 0 - ip */ su2ip_addr(&ip, snd_inf->to); s.s = ip_addr2a(&ip); s.len = strlen(s.s); return pv_get_strval(msg, param, res, &s); } return 0; }
struct service_provider* get_provider(struct sip_msg *msg, int attr, rw_lock_t *ref_lock ) { int vsp_addr_len; char *vsp_addr; //lock_start_read(ref_lock); LM_DBG("***************************attr\n "); struct service_provider* provider = *db_service_provider; while (provider != NULL) { LM_DBG("***************************attr:%d\n ", provider->attribution); if (provider->attribution == attr ){ if (provider->attribution == 2){ // busca ip vsp_addr = ip_addr2a(&msg->rcv.src_ip); vsp_addr_len = strlen(vsp_addr); LM_DBG("***************************vsp_addr:%s\n ", vsp_addr); LM_DBG("***************************provider IP:%.*s\n ", provider->nodeIP.len, provider->nodeIP.s); if ( (provider->nodeIP.len == vsp_addr_len) && (strncmp(vsp_addr, provider->nodeIP.s, vsp_addr_len) == 0)) { LM_DBG("***************************achou ip\n "); return provider; } }else{ return provider; } } provider = provider->next; } //lock_stop_read(ref_lock); return NULL; }