Exemple #1
0
/*
 * 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;
}
Exemple #2
0
/** 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;
}
Exemple #3
0
/** 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;
}
Exemple #4
0
/* 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;    
}
Exemple #5
0
/* 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);
		}
}
Exemple #6
0
/* 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);
	}
}
Exemple #7
0
/**
 * 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;
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #12
0
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;
}
Exemple #14
0
/* 
 * 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;
}
Exemple #15
0
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;
}
Exemple #16
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;
}
Exemple #19
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;
}
Exemple #20
0
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;

}
Exemple #21
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;
}
Exemple #22
0
// 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;
}
Exemple #23
0
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;
	}
}
Exemple #24
0
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;
}
Exemple #25
0
/*
 * 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;
}
Exemple #26
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;
}
Exemple #27
0
/**
 * @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;
}
Exemple #28
0
/*! \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;
}
Exemple #29
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;
}
Exemple #30
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;    
}