Ejemplo n.º 1
0
/**
* Add old IE support (Compatibility View) for POST requests by forcing a 2nd read on the
* server socket, to make IE send the POST body.
* Tests revealed that this mode does not change the behaviour for recent browser. Therefore,
* it can be used all the time. Option -i allows to disable it.
*
* @return 0 if successful, -1 otherwise
*/
int ie_compat_read_post_body(sock_t sock, request_t* req, proxenet_ssl_context_t* sslctx)
{
        int nb;
        size_t old_len, body_len;
        char *body, *clen;

        /* to speed-up, disregard requests without body */
        if (strcmp(req->http_infos.method, "POST")!=0 && \
            strcmp(req->http_infos.method, "PUT")!=0)
                return 0;

        /* read Content-Length header */
        clen = get_header_by_name(req->data, "Content-Length: ");
        if (!clen){
                xlog(LOG_ERROR, "%s\n", "Extending IE POST: No Content-Length");
                return -1;
        }

        /* if Content-Length is zero */
        body_len = (size_t)atoi(clen);
        proxenet_xfree(clen);

        if (body_len==0){
                return 0;
        }

        /* if everything has already been sent (i.e. end of already received buffer is not CRLF*2) */
        if (req->data[ req->size-4 ] != '\r')
                return 0;
        if (req->data[ req->size-3 ] != '\n')
                return 0;
        if (req->data[ req->size-2 ] != '\r')
                return 0;
        if (req->data[ req->size-1 ] != '\n')
                return 0;

        /* read data (if any) */
        nb = proxenet_read_all(sock, &body, sslctx);
        if (nb<0){
                xlog(LOG_ERROR, "%s\n", "Extending IE POST: failed to read");
                return -1;
        }

        /* and extend the request buffer */
        if (nb>0){
                old_len = req->size;
                req->size = old_len + (size_t)nb;
                req->data = proxenet_xrealloc(req->data, req->size);
                memcpy(req->data + old_len, body, (size_t)nb);
        }

        proxenet_xfree(body);

#ifdef DEBUG
        xlog(LOG_DEBUG, "Extending request for IE: new_size=%d (content-length=%d)\n",
             req->size, body_len);
#endif

        return 0;
}
Ejemplo n.º 2
0
/*
 * Get OSP token from SIP message
 * param msg SIP message
 * param token OSP authorization token
 * param tokensize Size of OSP authorization token
 * return 0 success, -1 failure
 */
int ospGetOspHeader(
    struct sip_msg* msg,
    unsigned char* token,
    unsigned int* tokensize)
{
    struct hdr_field* hf;
    int errorcode;
    int result = -1;

    if (parse_headers(msg, HDR_EOH_F, 0) != 0) {
        LM_ERR("failed to parse all headers\n");
    } else {
        hf = get_header_by_name(msg, OSP_TOKEN_HEADER, OSP_HEADER_SIZE);
        if (hf) {
            if ((errorcode = OSPPBase64Decode(hf->body.s, hf->body.len, token, tokensize)) == OSPC_ERR_NO_ERROR) {
                result = 0;
            } else {
                LM_ERR("failed to base64 decode token (%d)\n", errorcode);
                LM_ERR("header '%.*s' length %d\n",
                    hf->body.len, hf->body.s, hf->body.len);
            }
        }
    }

    return result;
}
Ejemplo n.º 3
0
/*! \brief
 */
static int set_sock_hdr(struct sip_msg *msg, ucontact_info_t *ci,
                        unsigned int reg_flags)
{
	struct socket_info *sock;
	struct hdr_field *hf;
	str socks;
	str hosts;
	int port;
	int proto;

	if (!msg || !(reg_flags & REG_SAVE_SOCKET_FLAG))
		return 1;

	if (parse_headers( msg, HDR_EOH_F, 0) == -1) {
		LM_ERR("failed to parse message\n");
		return 1;
	}

	hf = get_header_by_name( msg, sock_hdr_name.s, sock_hdr_name.len);
	if (hf==0)
		return 1;

	trim_len( socks.len, socks.s, hf->body );
	if (socks.len==0)
		return 1;

	if (parse_phostport( socks.s, socks.len, &hosts.s, &hosts.len,
	&port, &proto)!=0) {
		LM_ERR("bad socket <%.*s> in \n",
			socks.len, socks.s);
		return 1;
	}
	set_sip_defaults( port, proto);
	sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto);
	if (sock==0) {
		LM_ERR("non-local socket <%.*s>\n",	socks.len, socks.s);
		return 1;
	}

	LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port,sock );

	ci->sock = sock;
	return 0;
}
Ejemplo n.º 4
0
int tm_has_request_disponsition_no_cancel(struct sip_msg *msg)
{
	str RD_hdr_name = {"Request-Disposition",19};
	str opt = {"no-cancel",9};
	struct hdr_field *hdr;

	/* be sure all SIP headers are parsed */
	if (parse_headers(msg, HDR_EOH_F, 0) < 0) {
		LM_ERR("failed to parse SIP headers while looking for "
			"Request-Disposition\n");
		return -1;
	}

	hdr = get_header_by_name( msg, RD_hdr_name.s, RD_hdr_name.len);
	if (hdr==NULL)
		return -1;

	return list_hdr_has_option( hdr, &opt);
}
Ejemplo n.º 5
0
/*! \brief
 */
static struct socket_info *get_sock_hdr(struct sip_msg *msg)
{
	struct socket_info *sock;
	struct hdr_field *hf;
	str socks;
	str hosts;
	int port;
	int proto;

	if (parse_headers( msg, HDR_EOH_F, 0) == -1) {
		LM_ERR("failed to parse message\n");
		return 0;
	}

	hf = get_header_by_name( msg, sock_hdr_name.s, sock_hdr_name.len);
	if (hf==0)
		return 0;

	trim_len( socks.len, socks.s, hf->body );
	if (socks.len==0)
		return 0;

	if (parse_phostport( socks.s, socks.len, &hosts.s, &hosts.len, 
	&port, &proto)!=0) {
		LM_ERR("bad socket <%.*s> in \n",
			socks.len, socks.s);
		return 0;
	}
	set_sip_defaults( port, proto);
	sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto);
	if (sock==0) {
		LM_ERR("non-local socket <%.*s>\n",	socks.len, socks.s);
		return 0;
	}

	LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port_no,sock );

	return sock;
}
Ejemplo n.º 6
0
static int get_hostname_from_header(request_t *req)
{
        char *ptr, *header;

        header = get_header_by_name(req->data, "Host:");
        if (!header){
                return -1;
        }

        /* if port number, copy it */
        ptr = strchr(header, ':');
        if (ptr){
                *ptr = '\0';
                req->http_infos.hostname = proxenet_xstrdup2(header);
                req->http_infos.port = (unsigned short)atoi(ptr+1);
        } else {
                req->http_infos.hostname = proxenet_xstrdup2(header);
        }

        proxenet_xfree(header);

        return 0;
}
Ejemplo n.º 7
0
/**
 * This function updates all the fields of the current request_t with the new values found in the
 * request. Since those values will be useful many times, they are strdup-ed in a specific structure
 * (http_infos_t). Those values *must* be free-ed later on.
 *
 * @return 0 if successful, -1 if any error occurs.
 */
int parse_http_request(request_t *req)
{
        char *ptr, *buf, c;
        int offset;

        buf = req->data;

        /* method */
        ptr = strchr(buf, ' ');
        if (!ptr){
                xlog(LOG_ERROR, "%s\n", "Cannot find HTTP method in request");
                if (cfg->verbose)
                        xlog(LOG_ERROR, "Buffer sent:\n%s\n", buf);
                return -1;
        }

        c = *ptr;
        *ptr = '\0';
        req->http_infos.method = proxenet_xstrdup2(buf);
        if (!req->http_infos.method){
                xlog(LOG_ERROR, "%s\n", "strdup(method) failed, cannot pursue...");
                return -1;
        }

        *ptr = c;

        req->http_infos.proto_type = HTTP;
        if (!strcmp(req->http_infos.method, "CONNECT")){
                /*
                 * We can receive a CONNECT if
                 * - the connection uses HTTPS
                 * - the client tries to upgrade to WebSocket/Secure WebSocket
                 */
                char *upgrade_header = get_header_by_name(buf, "Upgrade:");
                if (upgrade_header){
                        if (strcmp(upgrade_header, "WebSocket")==0){
                                xlog(LOG_INFO, "%s\n", "Upgrading to WebSocket");
                                req->http_infos.proto_type = WS;
                                req->is_ssl = false;
                                req->http_infos.proto = WS_STRING;
                                req->http_infos.port = HTTP_DEFAULT_PORT;
                                req->http_infos.proto_type = WS;
                        }
                        proxenet_xfree(upgrade_header);
                } else {
                        req->is_ssl = true;
                        req->http_infos.proto = HTTPS_STRING;
                        req->http_infos.port = HTTPS_DEFAULT_PORT;
                        req->http_infos.proto_type = HTTPS;
                }

                offset = ptr - buf + 1;

                if( get_hostname_from_uri(req, offset) < 0 ){
                        xlog(LOG_ERROR, "%s\n", "Failed to get hostname (URI)");
                        goto failed_hostname;
                }

                req->http_infos.path = proxenet_xstrdup2("/");
                req->http_infos.version = proxenet_xstrdup2("HTTP/1.0");

                req->http_infos.uri = get_request_full_uri(req);
                if(!req->http_infos.uri){
                        xlog(LOG_ERROR, "%s\n", "get_request_full_uri() failed");
                        goto failed_uri;
                }

                return 0;
        }


        /* hostname and port */
        if (req->is_ssl){
                req->http_infos.port = HTTPS_DEFAULT_PORT;
                req->http_infos.proto = HTTPS_STRING;
        } else {
                req->http_infos.port = HTTP_DEFAULT_PORT;
                req->http_infos.proto = HTTP_STRING;
        }

        if( get_hostname_from_header(req) < 0 ){
                xlog(LOG_ERROR, "%s\n", "Failed to get hostname (Host header)");
                goto failed_hostname;
        }


        /* path */
        buf = ptr+1;

        if (!strncmp(buf, HTTP_PROTO_STRING, strlen(HTTP_PROTO_STRING))){
                buf = strchr(buf + 8, '/');
        }

        ptr = strchr(buf, ' ');
        if (!ptr){
                xlog(LOG_ERROR, "%s\n", "Cannot find HTTP path in request");
                goto failed_path;
        }

        c = *ptr;
        *ptr = '\0';
        req->http_infos.path = proxenet_xstrdup2(buf);
        if (!req->http_infos.path){
                xlog(LOG_ERROR, "%s\n", "strdup(path) failed, cannot pursue...");
                goto failed_path;
        }
        *ptr = c;

        buf = ptr+1;


        /* version */
        ptr = strchr(req->data, '\r');
        if (!ptr){
                xlog(LOG_ERROR, "%s\n", "Cannot find HTTP version");
                goto failed_version;
        }

        c = *ptr;
        *ptr = '\0';
        req->http_infos.version = proxenet_xstrdup2(buf);
        if (!req->http_infos.version){
                xlog(LOG_ERROR, "%s\n", "strdup(version) failed, cannot pursue...");
                goto failed_version;
        }
        *ptr = c;


        /* refresh uri */
        req->http_infos.uri = get_request_full_uri(req);
        if(!req->http_infos.uri){
                xlog(LOG_ERROR, "%s\n", "get_request_full_uri() failed");
                goto failed_uri;
        }


        if (cfg->verbose) {
                xlog(LOG_INFO, "New request %d to '%s'\n",
                     req->id, req->http_infos.uri);

                if (cfg->verbose > 1) {
                        xlog(LOG_INFO,
                             "Request HTTP information:\n"
                             "method=%s\n"
                             "proto=%s\n"
                             "hostname=%s\n"
                             "port=%d\n"
                             "path=%s\n"
                             "version=%s\n"
                             ,
                             req->http_infos.method,
                             req->http_infos.proto,
                             req->http_infos.hostname,
                             req->http_infos.port,
                             req->http_infos.path,
                             req->http_infos.version);
                }
        }

        return 0;


failed_uri:
        proxenet_xfree(req->http_infos.version);

failed_version:
        proxenet_xfree(req->http_infos.path);

failed_path:
        proxenet_xfree(req->http_infos.hostname);

failed_hostname:
        proxenet_xfree(req->http_infos.method);

        return -1;
}
Ejemplo n.º 8
0
/* Take headers to pass on the other side:
 *	Content-Type: 
 *	Allow: 
 *	Supported:
 *	Require
 *	RSeq
 *	Session-Expires
 *	Min-SE
*/
int b2b_extra_headers(struct sip_msg* msg, str* b2bl_key, str* custom_hdrs, str* extra_headers)
{
	char* p;
	struct hdr_field* require_hdr;
	struct hdr_field* rseq_hdr;
	struct hdr_field* subscription_state_hdr;
	struct hdr_field* hdr;
	struct hdr_field* hdrs[HDR_LST_LEN + HDR_DEFAULT_LEN];
	int hdrs_no = 0;
	int len = 0;
	int i;
	int custom_hdrs_len = 0;

	if(msg->content_type)
		hdrs[hdrs_no++] = msg->content_type;
	if(msg->supported)
		hdrs[hdrs_no++] = msg->supported;
	if(msg->allow)
		hdrs[hdrs_no++] = msg->allow;
	if(msg->proxy_require)
		hdrs[hdrs_no++] = msg->proxy_require;
	if(msg->session_expires)
		hdrs[hdrs_no++] = msg->session_expires;
	if(msg->min_se)
		hdrs[hdrs_no++] = msg->min_se;
	if(msg->maxforwards)
		hdrs[hdrs_no++] = msg->maxforwards;
	if(msg->event)
		hdrs[hdrs_no++] = msg->event;
	

	require_hdr = get_header_by_static_name( msg, "Require");
	if(require_hdr)
		hdrs[hdrs_no++] = require_hdr;

	rseq_hdr = get_header_by_static_name( msg, "RSeq");
	if(rseq_hdr)
		hdrs[hdrs_no++] = rseq_hdr;

	subscription_state_hdr = get_header_by_static_name( msg, "Subscription-state");
	if(subscription_state_hdr)
		hdrs[hdrs_no++] = subscription_state_hdr;

	/* add also the custom headers */
	for(i = 0; i< custom_headers_lst_len; i++)
	{
		hdr = get_header_by_name( msg, custom_headers_lst[i].s,
				custom_headers_lst[i].len);
		if(hdr)
		{
			hdrs[hdrs_no++] = hdr;
		}
	}

	/* calculate the length*/
	for(i = 0; i< hdrs_no; i++)
		len += hdrs[i]->len;

	if(init_callid_hdr.len && msg && msg->callid)
		len+= init_callid_hdr.len + msg->callid->len;

	if(len == 0)
		return 0;

	if(custom_hdrs && custom_hdrs->s && custom_hdrs->len)
	{
		custom_hdrs_len = custom_hdrs->len;
		len += custom_hdrs_len;
	}
	extra_headers->s = (char*)pkg_malloc(len);
	if(extra_headers->s == NULL)
	{
		LM_ERR("No more memory\n");
		return -1;
	}

	p = extra_headers->s;

	/* construct the headers string */
	for(i = 0; i< hdrs_no; i++)
	{
		memcpy(p, hdrs[i]->name.s, hdrs[i]->len);
		p += hdrs[i]->len;
	}
	if(custom_hdrs_len)
	{
		memcpy(p, custom_hdrs->s, custom_hdrs_len);
		p += custom_hdrs_len;
	}

	if(init_callid_hdr.s && msg && msg->callid)
	{
		memcpy(p, init_callid_hdr.s, init_callid_hdr.len);
		p += init_callid_hdr.len;
		len = sprintf(p, ": %.*s",
			(int)(msg->callid->name.s +msg->callid->len -msg->callid->body.s),
			msg->callid->body.s);
		p += len;
	}

	extra_headers->len = p - extra_headers->s;

	return 0;
}
Ejemplo n.º 9
0
int b2b_extra_headers(struct sip_msg* msg, str* b2bl_key, str* custom_hdrs,
															str* extra_headers)
{
	char* p;
	struct hdr_field* require_hdr;
	struct hdr_field* rseq_hdr;
	struct hdr_field* subscription_state_hdr;
	struct hdr_field* hdr;
	struct hdr_field* hdrs[HDR_LST_LEN + HDR_DEFAULT_LEN];
	regmatch_t pmatch;
	int hdrs_no = 0;
	int len = 0;
	int i;
	int custom_hdrs_len = 0;
	char tmp;

	if(msg->content_type)
		hdrs[hdrs_no++] = msg->content_type;
	if(msg->supported)
		hdrs[hdrs_no++] = msg->supported;
	if(msg->allow)
		hdrs[hdrs_no++] = msg->allow;
	if(msg->proxy_require)
		hdrs[hdrs_no++] = msg->proxy_require;
	if(msg->session_expires)
		hdrs[hdrs_no++] = msg->session_expires;
	if(msg->min_se)
		hdrs[hdrs_no++] = msg->min_se;
	if(msg->event)
		hdrs[hdrs_no++] = msg->event;


	require_hdr = get_header_by_static_name( msg, "Require");
	if(require_hdr)
		hdrs[hdrs_no++] = require_hdr;

	rseq_hdr = get_header_by_static_name( msg, "RSeq");
	if(rseq_hdr)
		hdrs[hdrs_no++] = rseq_hdr;

	subscription_state_hdr = get_header_by_static_name( msg,
		"Subscription-state");
	if(subscription_state_hdr)
		hdrs[hdrs_no++] = subscription_state_hdr;

	/* add also the custom headers */
	for(i = 0; i< custom_headers_lst_len; i++)
	{
		hdr = get_header_by_name( msg, custom_headers_lst[i].s,
				custom_headers_lst[i].len);
		if(hdr)
		{
			hdrs[hdrs_no++] = hdr;
		}
	}

	if (custom_headers_re)
	{
		for (hdr=msg->headers; hdr; hdr=hdr->next) {
			tmp = hdr->name.s[hdr->name.len];
			hdr->name.s[hdr->name.len] = '\0';
			i = regexec(custom_headers_re, hdr->name.s, 1, &pmatch, 0);
			hdr->name.s[hdr->name.len] = tmp;

			if (i == 0)
			{
				/* check if added twice */
				for(i = 0; i < hdrs_no; i++)
				{
					if ( hdrs[i]->name.len == hdr->name.len &&
					strncmp(hdrs[i]->name.s, hdr->name.s, hdr->name.len)==0 )
						break;
				}
				if (i == hdrs_no) /* Doubles not found -> add it */
					hdrs[hdrs_no++] = hdr;
			}
		}
	}

	/* calculate the length*/
	for(i = 0; i< hdrs_no; i++)
		len += hdrs[i]->len;

	if(init_callid_hdr.len && msg && msg->callid)
		len+= init_callid_hdr.len + msg->callid->len;

	if(custom_hdrs && custom_hdrs->s && custom_hdrs->len)
	{
		custom_hdrs_len = custom_hdrs->len;
		len += custom_hdrs_len;
	}

	if(len == 0) return 0;

	extra_headers->s = (char*)pkg_malloc(len);
	if(extra_headers->s == NULL)
	{
		LM_ERR("No more memory\n");
		return -1;
	}

	p = extra_headers->s;

	/* construct the headers string */
	for(i = 0; i< hdrs_no; i++)
	{
		memcpy(p, hdrs[i]->name.s, hdrs[i]->len);
		p += hdrs[i]->len;
	}
	if(custom_hdrs_len)
	{
		memcpy(p, custom_hdrs->s, custom_hdrs_len);
		p += custom_hdrs_len;
	}

	if(init_callid_hdr.s && msg && msg->callid)
	{
		memcpy(p, init_callid_hdr.s, init_callid_hdr.len);
		p += init_callid_hdr.len;
		len = sprintf(p, ": %.*s",
			(int)(msg->callid->name.s +msg->callid->len -msg->callid->body.s),
			msg->callid->body.s);
		p += len;
	}

	extra_headers->len = p - extra_headers->s;

	return 0;
}