예제 #1
0
파일: osip_header.c 프로젝트: avis/osip
/* returns -1 on error. */
int
osip_message_set_header(osip_message_t * sip, const char *hname,
						const char *hvalue)
{
	osip_header_t *h;
	int i;

	if (sip == NULL || hname == NULL)
		return OSIP_BADPARAMETER;

	i = osip_header_init(&h);
	if (i != 0)
		return i;

	h->hname = (char *) osip_malloc(strlen(hname) + 1);

	if (h->hname == NULL) {
		osip_header_free(h);
		return OSIP_NOMEM;
	}
	osip_clrncpy(h->hname, hname, strlen(hname));

	if (hvalue != NULL) {		/* some headers can be null ("subject:") */
		h->hvalue = (char *) osip_malloc(strlen(hvalue) + 1);
		if (h->hvalue == NULL) {
			osip_header_free(h);
			return OSIP_NOMEM;
		}
		osip_clrncpy(h->hvalue, hvalue, strlen(hvalue));
	} else
		h->hvalue = NULL;
	sip->message_property = 2;
	osip_list_add(&sip->headers, h, -1);
	return OSIP_SUCCESS;		/* ok */
}
예제 #2
0
/* returns -1 on error. */
int
osip_cseq_parse (osip_cseq_t * cseq, const char *hvalue)
{
  char *method = NULL;
  const char *end = NULL;

  cseq->number = NULL;
  cseq->method = NULL;

  method = strchr (hvalue, ' ');        /* SEARCH FOR SPACE */
  end = hvalue + strlen (hvalue);

  if (method == NULL)
    return -1;

  if (method - hvalue + 1 < 2)
    return -1;
  cseq->number = (char *) osip_malloc (method - hvalue + 1);
  if (cseq->number == NULL)
    return -1;
  osip_clrncpy (cseq->number, hvalue, method - hvalue);

  if (end - method + 1 < 2)
    return -1;
  cseq->method = (char *) osip_malloc (end - method + 1);
  if (cseq->method == NULL)
    return -1;
  osip_clrncpy (cseq->method, method + 1, end - method);

  return 0;                     /* ok */
}
예제 #3
0
파일: osip_cseq.c 프로젝트: avis/osip
/* returns -1 on error. */
int osip_cseq_parse(osip_cseq_t * cseq, const char *hvalue)
{
	char *method = NULL;
	const char *end = NULL;

	if (cseq == NULL || hvalue == NULL)
		return OSIP_BADPARAMETER;

	cseq->number = NULL;
	cseq->method = NULL;

	method = strchr(hvalue, ' ');	/* SEARCH FOR SPACE */
	if (method == NULL)
		return OSIP_SYNTAXERROR;

	end = hvalue + strlen(hvalue);

	if (method - hvalue + 1 < 2)
		return OSIP_SYNTAXERROR;
	cseq->number = (char *) osip_malloc(method - hvalue + 1);
	if (cseq->number == NULL)
		return OSIP_NOMEM;
	osip_clrncpy(cseq->number, hvalue, method - hvalue);

	if (end - method + 1 < 2)
		return OSIP_SYNTAXERROR;
	cseq->method = (char *) osip_malloc(end - method + 1);
	if (cseq->method == NULL)
		return OSIP_NOMEM;
	osip_clrncpy(cseq->method, method + 1, end - method);

	return OSIP_SUCCESS;		/* ok */
}
예제 #4
0
/* returns -1 on error. */
int osip_content_type_parse(osip_content_type_t * content_type, const char *hvalue)
{
	char *subtype;
	char *osip_content_type_params;
	int i;

	/* How to parse:

	   we'll place the pointers:
	   subtype              =>  beginning of subtype
	   osip_content_type_params  =>  beginning of params

	   examples:

	   application/multipart ; boundary=
	   ^          ^
	 */
	if (hvalue == NULL || hvalue[0] == '\0')
		return OSIP_SUCCESS;	/* It's valid to add empty Accept header! */

	subtype = strchr(hvalue, '/');
	osip_content_type_params = strchr(hvalue, ';');

	if (subtype == NULL)
		return OSIP_SYNTAXERROR;	/* do we really mind such an error */

	if (osip_content_type_params != NULL) {
		i = __osip_generic_param_parseall(&content_type->gen_params,
										  osip_content_type_params);
		if (i != 0)
			return i;
	} else
		osip_content_type_params = subtype + strlen(subtype);

	if (subtype - hvalue + 1 < 2)
		return OSIP_SYNTAXERROR;
	content_type->type = (char *) osip_malloc(subtype - hvalue + 1);
	if (content_type->type == NULL)
		return OSIP_NOMEM;
	osip_clrncpy(content_type->type, hvalue, subtype - hvalue);

	if (osip_content_type_params - subtype < 2)
		return OSIP_SYNTAXERROR;
	content_type->subtype =
		(char *) osip_malloc(osip_content_type_params - subtype);
	if (content_type->subtype == NULL)
		return OSIP_NOMEM;
	osip_clrncpy(content_type->subtype, subtype + 1,
				 osip_content_type_params - subtype - 1);

	return OSIP_SUCCESS;
}
예제 #5
0
int
osip_call_info_parse (osip_call_info_t * call_info, const char *hvalue)
{
  const char *osip_call_info_params;

  osip_call_info_params = strchr (hvalue, '<');
  if (osip_call_info_params == NULL)
    return -1;

  osip_call_info_params = strchr (osip_call_info_params + 1, '>');
  if (osip_call_info_params == NULL)
    return -1;

  osip_call_info_params = strchr (osip_call_info_params + 1, ';');

  if (osip_call_info_params != NULL)
    {
      if (__osip_generic_param_parseall
          (call_info->gen_params, osip_call_info_params) == -1)
        return -1;
  } else
    osip_call_info_params = hvalue + strlen (hvalue);

  if (osip_call_info_params - hvalue + 1 < 2)
    return -1;
  call_info->element = (char *) osip_malloc (osip_call_info_params - hvalue + 1);
  if (call_info->element == NULL)
    return -1;
  osip_clrncpy (call_info->element, hvalue, osip_call_info_params - hvalue);

  return 0;
}
int
osip_accept_encoding_parse (osip_accept_encoding_t * accept_encoding,
                            const char *hvalue)
{
  const char *osip_accept_encoding_params;

  osip_accept_encoding_params = strchr (hvalue, ';');

  if (osip_accept_encoding_params != NULL)
    {
      if (__osip_generic_param_parseall (&accept_encoding->gen_params,
                                         osip_accept_encoding_params) == -1)
        return -1;
  } else
    osip_accept_encoding_params = hvalue + strlen (hvalue);

  if (osip_accept_encoding_params - hvalue + 1 < 2)
    return -1;
  accept_encoding->element =
    (char *) osip_malloc (osip_accept_encoding_params - hvalue + 1);
  if (accept_encoding->element == NULL)
    return -1;
  osip_clrncpy (accept_encoding->element, hvalue,
                osip_accept_encoding_params - hvalue);

  return 0;
}
int
osip_accept_encoding_parse(osip_accept_encoding_t * accept_encoding,
						   const char *hvalue)
{
	int i;
	const char *osip_accept_encoding_params;

	osip_accept_encoding_params = strchr(hvalue, ';');

	if (osip_accept_encoding_params != NULL) {
		i = __osip_generic_param_parseall(&accept_encoding->gen_params,
										  osip_accept_encoding_params);
		if (i != 0)
			return i;
	} else
		osip_accept_encoding_params = hvalue + strlen(hvalue);

	if (osip_accept_encoding_params - hvalue + 1 < 2)
		return OSIP_SYNTAXERROR;
	accept_encoding->element =
		(char *) osip_malloc(osip_accept_encoding_params - hvalue + 1);
	if (accept_encoding->element == NULL)
		return OSIP_NOMEM;
	osip_clrncpy(accept_encoding->element, hvalue,
				 osip_accept_encoding_params - hvalue);

	return OSIP_SUCCESS;
}
int
osip_call_info_parse (osip_call_info_t * call_info, const char *hvalue)
{
  const char *osip_call_info_params;
  int i;

  osip_call_info_params = strchr (hvalue, '<');
  if (osip_call_info_params == NULL)
    return OSIP_SYNTAXERROR;

  osip_call_info_params = strchr (osip_call_info_params + 1, '>');
  if (osip_call_info_params == NULL)
    return OSIP_SYNTAXERROR;

  osip_call_info_params = strchr (osip_call_info_params + 1, ';');

  if (osip_call_info_params != NULL)
    {
	  i = __osip_generic_param_parseall(&call_info->gen_params, osip_call_info_params);
      if (i != 0)
        return i;
  } else
    osip_call_info_params = hvalue + strlen (hvalue);

  if (osip_call_info_params - hvalue + 1 < 2)
    return OSIP_SYNTAXERROR;
  call_info->element = (char *) osip_malloc (osip_call_info_params - hvalue + 1);
  if (call_info->element == NULL)
    return OSIP_NOMEM;
  osip_clrncpy (call_info->element, hvalue, osip_call_info_params - hvalue);

  return OSIP_SUCCESS;
}
예제 #9
0
/* returns -1 on error. */
int
osip_message_replace_header (osip_message_t * sip, const char *hname,
			     const char *hvalue)
{
  osip_header_t *h, *oldh;
  int i, oldpos = -1;

  if (sip == NULL || hname == NULL)
    return OSIP_BADPARAMETER;

  oldpos = osip_message_header_get_byname(sip, hname, 0, &oldh);

  i = osip_header_init (&h);
  if (i != 0)
    return i;

  h->hname = (char *) osip_malloc (strlen (hname) + 1);

  if (h->hname == NULL)
    {
      osip_header_free (h);
      return OSIP_NOMEM;
    }
  osip_clrncpy (h->hname, hname, strlen (hname));

  if (hvalue != NULL)
    {                           /* some headers can be null ("subject:") */
      h->hvalue = (char *) osip_malloc (strlen (hvalue) + 1);
      if (h->hvalue == NULL)
	{
	  osip_header_free (h);
	  return OSIP_NOMEM;
	}
      osip_clrncpy (h->hvalue, hvalue, strlen (hvalue));
    } else
      h->hvalue = NULL;

  if (oldpos != -1)
    {
      osip_list_remove(&sip->headers, oldpos);
      osip_header_free(oldh);
    }

  sip->message_property = 2;
  osip_list_add (&sip->headers, h, -1);
  return OSIP_SUCCESS;                     /* ok */
}
예제 #10
0
int
osip_content_disposition_parse (osip_content_disposition_t * cd,
                                const char *hvalue)
{
  const char *cd_params;

  cd_params = strchr (hvalue, ';');

  if (cd_params != NULL)
    {
      if (__osip_generic_param_parseall (&cd->gen_params, cd_params) == -1)
        return -1;
  } else
    cd_params = hvalue + strlen (hvalue);

  if (cd_params - hvalue + 1 < 2)
    return -1;
  cd->element = (char *) osip_malloc (cd_params - hvalue + 1);
  if (cd->element == NULL)
    return -1;
  osip_clrncpy (cd->element, hvalue, cd_params - hvalue);

  return 0;
}
예제 #11
0
int
__osip_token_set (const char *name, const char *str, char **result, const char **next)
{
  const char *beg;
  const char *tmp;

  *next = str;
  if (*result != NULL)
    return OSIP_SUCCESS;        /* already parsed */
  *next = NULL;

  beg = strchr (str, '=');
  if (beg == NULL)
    return OSIP_SYNTAXERROR;    /* bad header format... */

  if (strlen (str) < 6)
    return OSIP_SUCCESS;        /* end of header... */

  while ((' ' == *str) || ('\t' == *str) || (',' == *str))
    if (*str)
      str++;
    else
      return OSIP_SYNTAXERROR;  /* bad header format */

  if (osip_strncasecmp (name, str, strlen (name)) == 0) {
    const char *end;

    end = strchr (str, ',');
    if (end == NULL)
      end = str + strlen (str); /* This is the end of the header */

    if (end - beg < 2)
      return OSIP_SYNTAXERROR;
    *result = (char *) osip_malloc (end - beg);
    if (*result == NULL)
      return OSIP_NOMEM;
    osip_clrncpy (*result, beg + 1, end - beg - 1);

    /* make sure the element does not contain more parameter */
    tmp = (*end) ? (end + 1) : end;
    for (; *tmp == ' ' || *tmp == '\t'; tmp++) {
    }
    for (; *tmp == '\n' || *tmp == '\r'; tmp++) {
    }                           /* skip LWS */
    *next = NULL;
    if (*tmp == '\0')           /* end of header detected */
      return OSIP_SUCCESS;
    if (*tmp != '\t' && *tmp != ' ')
      /* LWS here ? */
      *next = tmp;
    else {                      /* it is: skip it... */
      for (; *tmp == ' ' || *tmp == '\t'; tmp++) {
      }
      if (*tmp == '\0')         /* end of header detected */
        return OSIP_SUCCESS;
      *next = tmp;
    }
  }
  else
    *next = str;                /* next element start here */
  return OSIP_SUCCESS;
}
예제 #12
0
int
osip_message_set_multiple_header(osip_message_t * sip, char *hname, char *hvalue)
{
	int i;
	char *ptr;					/* current location of the search */
	char *comma;				/* This is the separator we are elooking for */
	char *beg;					/* beg of a header */
	char *end;					/* end of a header */
	char *quote1;				/* first quote of a pair of quotes   */
	char *quote2;				/* second quuote of a pair of quotes */
	size_t hname_len;

	/* Find header based upon lowercase comparison */
	osip_tolower(hname);

	if (hvalue == NULL) {
		i = osip_message_set__header(sip, hname, hvalue);
		if (i != 0)
			return i;
		return OSIP_SUCCESS;
	}

	ptr = hvalue;
	comma = strchr(ptr, ',');

	hname_len = strlen(hname);

	if (comma == NULL || (hname_len == 4 && strncmp(hname, "date", 4) == 0)
		|| (hname_len == 2 && strncmp(hname, "to", 2) == 0)
		|| (hname_len == 4 && strncmp(hname, "from", 4) == 0)
		|| (hname_len == 7 && strncmp(hname, "call-id", 7) == 0)
		|| (hname_len == 4 && strncmp(hname, "cseq", 4) == 0)
		|| (hname_len == 7 && strncmp(hname, "subject", 7) == 0)
		|| (hname_len == 7 && strncmp(hname, "expires", 7) == 0)
		|| (hname_len == 6 && strncmp(hname, "server", 6) == 0)
		|| (hname_len == 10 && strncmp(hname, "user-agent", 10) == 0)
		|| (hname_len == 16 && strncmp(hname, "www-authenticate", 16) == 0)
		|| (hname_len == 19 && strncmp(hname, "authentication-info", 19) == 0)
		|| (hname_len == 18 && strncmp(hname, "proxy-authenticate", 18) == 0)
		|| (hname_len == 19 && strncmp(hname, "proxy-authorization", 19) == 0)
		|| (hname_len == 25
			&& strncmp(hname, "proxy-authentication-info", 25) == 0)
		|| (hname_len == 12 && strncmp(hname, "organization", 12) == 0)
		|| (hname_len == 13 && strncmp(hname, "authorization", 13) == 0))
		/* there is no multiple header! likely      */
		/* to happen most of the time...            */
		/* or hname is a TEXT-UTF8-TRIM and may     */
		/* contain a comma. this is not a separator */
		/* THIS DOES NOT WORK FOR UNKNOWN HEADER!!!! */
	{
		i = osip_message_set__header(sip, hname, hvalue);
		if (i != 0)
			return i;
		return OSIP_SUCCESS;
	}

	beg = hvalue;
	end = NULL;
	quote2 = NULL;
	while (comma != NULL) {
		quote1 = __osip_quote_find(ptr);
		if (quote1 != NULL) {
			quote2 = __osip_quote_find(quote1 + 1);
			if (quote2 == NULL)
				return OSIP_SYNTAXERROR;	/* quotes comes by pair */
			ptr = quote2 + 1;
		}

		if ((quote1 == NULL) || (quote1 > comma)) {
			/* We must search for the next comma which is not
			   within quotes! */
			end = comma;

			if (quote1 != NULL && quote1 > comma) {
				/* comma may be within the quotes */
				/* ,<sip:[email protected]>;methods=\"INVITE,BYE,OPTIONS,ACK,CANCEL\",<sip:[email protected]> */
				/* we want the next comma after the quotes */
				char *tmp_comma;
				char *tmp_quote1;
				char *tmp_quote2;

				tmp_quote1 = quote1;
				tmp_quote2 = quote2;
				tmp_comma = strchr(comma + 1, ',');
				while (1) {
					if (tmp_comma < tmp_quote1)
						break;	/* ok (before to quotes) */
					if (tmp_comma < tmp_quote2) {
						tmp_comma = strchr(tmp_quote2 + 1, ',');
					}
					tmp_quote1 = __osip_quote_find(tmp_quote2 + 1);
					if (tmp_quote1 == NULL)
						break;
					tmp_quote2 = __osip_quote_find(tmp_quote1 + 1);
					if (tmp_quote2 == NULL)
						break;	/* probably a malformed message? */
				}
				comma = tmp_comma;	/* this one is not enclosed within quotes */
			} else
				comma = strchr(comma + 1, ',');
			if (comma != NULL)
				ptr = comma + 1;

		} else if ((quote1 < comma) && (quote2 < comma)) {	/* quotes are located before the comma, */
			/* continue the search for next quotes  */
			ptr = quote2 + 1;
		} else if ((quote1 < comma) && (comma < quote2)) {	/* if comma is inside the quotes... */
			/* continue with the next comma.    */
			ptr = quote2 + 1;
			comma = strchr(ptr, ',');
			if (comma == NULL)
				/* this header last at the end of the line! */
			{					/* this one does not need an allocation... */
#if 0
				if (strlen(beg) < 2)
					return OSIP_SUCCESS;	/* empty header */
#else
				if (beg[0] == '\0' || beg[1] == '\0')
					return OSIP_SUCCESS;	/* empty header */
#endif
				osip_clrspace(beg);
				i = osip_message_set__header(sip, hname, beg);
				if (i != 0)
					return i;
				return OSIP_SUCCESS;
			}
		}

		if (end != NULL) {
			char *avalue;

			if (end - beg + 1 < 2)
				return OSIP_SYNTAXERROR;
			avalue = (char *) osip_malloc(end - beg + 1);
			if (avalue == NULL)
				return OSIP_NOMEM;
			osip_clrncpy(avalue, beg, end - beg);
			/* really store the header in the sip structure */
			i = osip_message_set__header(sip, hname, avalue);
			osip_free(avalue);
			if (i != 0)
				return i;
			beg = end + 1;
			end = NULL;
			if (comma == NULL)
				/* this header last at the end of the line! */
			{					/* this one does not need an allocation... */
#if 0
				if (strlen(beg) < 2)
					return OSIP_SUCCESS;	/* empty header */
#else
				if (beg[0] == '\0' || beg[1] == '\0')
					return OSIP_SUCCESS;	/* empty header */
#endif
				osip_clrspace(beg);
				i = osip_message_set__header(sip, hname, beg);
				if (i != 0)
					return i;
				return OSIP_SUCCESS;
			}
		}
	}
	return OSIP_SYNTAXERROR;	/* if comma is NULL, we should have already return 0 */
}
예제 #13
0
/* set all headers */
static int
msg_headers_parse(osip_message_t * sip, const char *start_of_header,
				  const char **body)
{
	const char *colon_index;	/* index of ':' */
	char *hname;
	char *hvalue;
	const char *end_of_header;
	int i;

	for (;;) {
		if (start_of_header[0] == '\0') {	/* final CRLF is missing */
			OSIP_TRACE(osip_trace
					   (__FILE__, __LINE__, OSIP_INFO1, NULL,
						"SIP message does not end with CRLFCRLF\n"));
			return OSIP_SUCCESS;
		}

		i = __osip_find_next_crlf(start_of_header, &end_of_header);
		if (i == -2) {
		} else if (i != 0) {
			OSIP_TRACE(osip_trace
					   (__FILE__, __LINE__, OSIP_ERROR, NULL,
						"End of header Not found\n"));
			return i;			/* this is an error case!     */
		}

		/* the list of headers MUST always end with  */
		/* CRLFCRLF (also CRCR and LFLF are allowed) */
		if ((start_of_header[0] == '\r') || (start_of_header[0] == '\n')) {
			*body = start_of_header;
			return OSIP_SUCCESS;	/* end of header found        */
		}

		/* find the header name */
		colon_index = strchr(start_of_header, ':');
		if (colon_index == NULL) {
			OSIP_TRACE(osip_trace
					   (__FILE__, __LINE__, OSIP_ERROR, NULL,
						"End of header Not found\n"));
			return OSIP_SYNTAXERROR;	/* this is also an error case */
		}
		if (colon_index - start_of_header + 1 < 2)
			return OSIP_SYNTAXERROR;
		if (end_of_header <= colon_index) {
			OSIP_TRACE(osip_trace
					   (__FILE__, __LINE__, OSIP_ERROR, NULL,
						"Malformed message\n"));
			return OSIP_SYNTAXERROR;
		}
		hname = (char *) osip_malloc(colon_index - start_of_header + 1);
		if (hname == NULL)
			return OSIP_NOMEM;
		osip_clrncpy(hname, start_of_header, colon_index - start_of_header);

		{
			const char *end;

			/* END of header is (end_of_header-2) if header separation is CRLF */
			/* END of header is (end_of_header-1) if header separation is CR or LF */
			if ((end_of_header[-2] == '\r') || (end_of_header[-2] == '\n'))
				end = end_of_header - 2;
			else
				end = end_of_header - 1;
			if ((end) - colon_index < 2)
				hvalue = NULL;	/* some headers (subject) can be empty */
			else {
				hvalue = (char *) osip_malloc((end) - colon_index + 1);
				if (hvalue == NULL) {
					osip_free(hname);
					return OSIP_NOMEM;
				}
				osip_clrncpy(hvalue, colon_index + 1, (end) - colon_index - 1);
			}
		}

		/* hvalue MAY contains multiple value. In this case, they   */
		/* are separated by commas. But, a comma may be part of a   */
		/* quoted-string ("here, and there" is an example where the */
		/* comma is not a separator!) */
		i = osip_message_set_multiple_header(sip, hname, hvalue);

		osip_free(hname);
		if (hvalue != NULL)
			osip_free(hvalue);
		if (i != 0) {
			OSIP_TRACE(osip_trace
					   (__FILE__, __LINE__, OSIP_ERROR, NULL,
						"End of header Not found\n"));
			return OSIP_SYNTAXERROR;
		}

		/* continue on the next header */
		start_of_header = end_of_header;
	}

/* Unreachable code
 OSIP_TRACE (osip_trace
	      (__FILE__, __LINE__, OSIP_BUG, NULL,
	       "This code cannot be reached\n")); */
	return OSIP_SYNTAXERROR;
}
예제 #14
0
static int
__osip_message_startline_parsereq(osip_message_t * dest, const char *buf,
								  const char **headers)
{
	const char *p1;
	const char *p2;
	char *requesturi;
	int i;

	dest->sip_method = NULL;
	dest->status_code = 0;
	dest->reason_phrase = NULL;

	*headers = buf;

	/* The first token is the method name: */
	p2 = strchr(buf, ' ');
	if (p2 == NULL)
		return OSIP_SYNTAXERROR;
	if (*(p2 + 1) == '\0' || *(p2 + 2) == '\0')
		return OSIP_SYNTAXERROR;
	if (p2 - buf == 0) {
		OSIP_TRACE(osip_trace
				   (__FILE__, __LINE__, OSIP_ERROR, NULL,
					"No space allowed here\n"));
		return OSIP_SYNTAXERROR;
	}
	dest->sip_method = (char *) osip_malloc(p2 - buf + 1);
	if (dest->sip_method == NULL)
		return OSIP_NOMEM;
	osip_strncpy(dest->sip_method, buf, p2 - buf);

	/* The second token is a sip-url or a uri: */
	p1 = strchr(p2 + 2, ' ');	/* no space allowed inside sip-url */
	if (p1 == NULL) {
		OSIP_TRACE(osip_trace
				   (__FILE__, __LINE__, OSIP_ERROR, NULL,
					"Uncompliant request-uri\n"));
		osip_free(dest->sip_method);
		dest->sip_method = NULL;
		return OSIP_SYNTAXERROR;
	}
	if (p1 - p2 < 2) {
		osip_free(dest->sip_method);
		dest->sip_method = NULL;
		return OSIP_SYNTAXERROR;
	}

	requesturi = (char *) osip_malloc(p1 - p2);
	if (requesturi == NULL) {
		osip_free(dest->sip_method);
		dest->sip_method = NULL;
		return OSIP_NOMEM;
	}
	osip_clrncpy(requesturi, p2 + 1, (p1 - p2 - 1));

	i = osip_uri_init(&(dest->req_uri));
	if (i != 0) {
		osip_free(requesturi);
		requesturi = NULL;
		osip_free(dest->sip_method);
		dest->sip_method = NULL;
		return OSIP_NOMEM;
	}
	i = osip_uri_parse(dest->req_uri, requesturi);
	osip_free(requesturi);
	if (i != 0) {
		osip_free(dest->sip_method);
		dest->sip_method = NULL;
		osip_uri_free(dest->req_uri);
		dest->req_uri = NULL;
		return OSIP_SYNTAXERROR;
	}

	/* find the the version and the beginning of headers */
	{
		const char *hp = p1;

		while ((*hp != '\r') && (*hp != '\n')) {
			if (*hp)
				hp++;
			else {
				OSIP_TRACE(osip_trace
						   (__FILE__, __LINE__, OSIP_ERROR, NULL,
							"No crlf found\n"));
				osip_free(dest->sip_method);
				dest->sip_method = NULL;
				osip_uri_free(dest->req_uri);
				dest->req_uri = NULL;
				return OSIP_SYNTAXERROR;
			}
		}
		if (hp - p1 < 2) {
			osip_free(dest->sip_method);
			dest->sip_method = NULL;
			osip_uri_free(dest->req_uri);
			dest->req_uri = NULL;
			return OSIP_SYNTAXERROR;
		}

		dest->sip_version = (char *) osip_malloc(hp - p1);
		if (dest->sip_version == NULL) {
			osip_free(dest->sip_method);
			dest->sip_method = NULL;
			osip_uri_free(dest->req_uri);
			dest->req_uri = NULL;
			return OSIP_NOMEM;
		}

		osip_strncpy(dest->sip_version, p1 + 1, (hp - p1 - 1));

		if (0 != osip_strcasecmp(dest->sip_version, "SIP/2.0")) {
			OSIP_TRACE(osip_trace
					   (__FILE__, __LINE__, OSIP_ERROR, NULL,
						"Wrong version number\n"));
		}

		hp++;
		if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0]))
			hp++;
		(*headers) = hp;
	}
	return OSIP_SUCCESS;
}
예제 #15
0
/* returns -1 on error. */
int
osip_from_parse (osip_from_t * from, const char *hvalue)
{
  const char *displayname;
  const char *url;
  const char *url_end;
  const char *gen_params;

  /* How to parse:

     we'll place the pointers:
     displayname  =>  beginning of displayname
     url          =>  beginning of url
     url_end      =>  end       of url
     gen_params  =>  beginning of params

     examples:

     jack <sip:[email protected]>;tag=34erZ
     ^     ^                ^ ^

     sip:[email protected];tag=34erZ
     ^                ^^      
   */

  displayname = strchr (hvalue, '"');

  url = strchr (hvalue, '<');
  if (url != NULL)
    {
      url_end = strchr (url, '>');
      if (url_end == NULL)
        return -1;
    }

  /* SIPit day2: this case was not supported
     first '"' is placed after '<' and after '>'
     <sip:[email protected];method=INVITE>;description="OPEN";expires=28800
     if the fisrt quote is after '<' then
     this is not a quote for a displayname.
   */
  if (displayname != NULL)
    {
      if (displayname > url)
        displayname = NULL;
    }

  if ((displayname == NULL) && (url != NULL))
    {                           /* displayname IS A '*token' (not a quoted-string) */
      if (hvalue != url)        /* displayname exists */
        {
          if (url - hvalue + 1 < 2)
            return -1;
          from->displayname = (char *) osip_malloc (url - hvalue + 1);
          if (from->displayname == NULL)
            return -1;
          osip_clrncpy (from->displayname, hvalue, url - hvalue);
        }
      url++;                    /* place pointer on the beginning of url */
  } else
    {
      if ((displayname != NULL) && (url != NULL))
        {                       /* displayname IS A quoted-string (not a '*token') */
          const char *first;
          const char *second=NULL;

          /* search for quotes */
          first = __osip_quote_find (hvalue);
          if (first == NULL)
            return -1;          /* missing quote */
	  second = __osip_quote_find (first + 1);
          if (second == NULL)
            return -1;          /* missing quote */
          if ((first > url))
            return -1;

          if (second - first + 2 >= 2)
            {
              from->displayname = (char *) osip_malloc (second - first + 2);
              if (from->displayname == NULL)
                return -1;
              osip_strncpy (from->displayname, first, second - first + 1);
              /* osip_clrspace(from->displayname); *//*should we do that? */

              /* special case: "<sip:[email protected]>" <sip:[email protected]> */
            }                   /* else displayname is empty? */
          url = strchr (second + 1, '<');
          if (url == NULL)
            return -1;          /* '<' MUST exist */
          url++;
      } else
        url = hvalue;           /* field does not contains '<' and '>' */
    }

  /* DISPLAY-NAME SET   */
  /* START of URL KNOWN */

  url_end = strchr (url, '>');

  if (url_end == NULL)          /* sip:[email protected];tag=023 */
    {                           /* We are sure ';' is the delimiter for from-parameters */
      char *host = strchr (url, '@');

      if (host != NULL)
        gen_params = strchr (host, ';');
      else
        gen_params = strchr (url, ';');
      if (gen_params != NULL)
        url_end = gen_params - 1;
      else
        url_end = url + strlen (url);
  } else                        /* jack <sip:[email protected];user=phone>;tag=azer */
    {
      gen_params = strchr (url_end, ';');
      url_end--;                /* place pointer on the beginning of url */
    }

  if (gen_params != NULL)       /* now we are sure a param exist */
    if (__osip_generic_param_parseall (&from->gen_params, gen_params) == -1)
      {
        return -1;
      }

  /* set the url */
  {
    char *tmp;
    int i;

    if (url_end - url + 2 < 7)
      return -1;
    i = osip_uri_init (&(from->url));
    if (i != 0)
      return -1;
    tmp = (char *) osip_malloc (url_end - url + 2);
    if (tmp == NULL)
      return -1;
    osip_strncpy (tmp, url, url_end - url + 1);
    i = osip_uri_parse (from->url, tmp);
    osip_free (tmp);
    if (i != 0)
      return -1;
  }
  return 0;
}
예제 #16
0
int
osip_via_parse (osip_via_t * via, const char *hvalue)
{
  const char *version;
  const char *protocol;
  const char *host;
  const char *ipv6host;
  const char *port;
  const char *via_params;
  const char *comment;

  version = strchr (hvalue, '/');
  if (version == NULL)
    return -1;

  protocol = strchr (version + 1, '/');
  if (protocol == NULL)
    return -1;

  /* set the version */
  if (protocol - version < 2)
    return -1;
  via->version = (char *) osip_malloc (protocol - version);
  if (via->version == NULL)
    return -1;
  osip_clrncpy (via->version, version + 1, protocol - version - 1);

  /* Here: we avoid matching an additionnal space */
  host = strchr (protocol + 1, ' ');
  if (host == NULL)
    return -1;                  /* fixed in 0.8.4 */
  if (host == protocol + 1)     /* there are extra SPACE characters */
    {
      while (0 == strncmp (host, " ", 1))
        {
          host++;
          if (strlen (host) == 1)
            return -1;          /* via is malformed */
        }
      /* here, we match the real space located after the protocol name */
      host = strchr (host + 1, ' ');
      if (host == NULL)
        return -1;              /* fixed in 0.8.4 */
    }

  /* set the protocol */
  if (host - protocol < 2)
    return -1;
  via->protocol = (char *) osip_malloc (host - protocol);
  if (via->protocol == NULL)
    return -1;
  osip_clrncpy (via->protocol, protocol + 1, host - protocol - 1);

  /* comments in Via are not allowed any more in the latest draft (09) */
  comment = strchr (host, '(');

  if (comment != NULL)
    {
      char *end_comment;

      end_comment = strchr (host, ')');
      if (end_comment == NULL)
        return -1;              /* if '(' exist ')' MUST exist */
      if (end_comment - comment < 2)
        return -1;
      via->comment = (char *) osip_malloc (end_comment - comment);
      if (via->comment == NULL)
        return -1;
      osip_strncpy (via->comment, comment + 1, end_comment - comment - 1);
      comment--;
  } else
    comment = host + strlen (host);

  via_params = strchr (host, ';');

  if ((via_params != NULL) && (via_params < comment))
    /* via params exist */
    {
      char *tmp;

      if (comment - via_params + 1 < 2)
        return -1;
      tmp = (char *) osip_malloc (comment - via_params + 1);
      if (tmp == NULL)
        return -1;
      osip_strncpy (tmp, via_params, comment - via_params);
      if (__osip_generic_param_parseall (&via->via_params, tmp))
        {
          osip_free (tmp);
          return -1;
        }

      osip_free (tmp);
    }

  if (via_params == NULL)
    via_params = comment;

  /* add ipv6 support (0.8.4) */
  /* Via: SIP/2.0/UDP [mlke::zeezf:ezfz:zef:zefzf]:port;.... */
  ipv6host = strchr (host, '[');
  if (ipv6host != NULL && ipv6host < via_params)
    {
      port = strchr (ipv6host, ']');
      if (port == NULL || port > via_params)
        return -1;

      if (port - ipv6host < 2)
        return -1;
      via->host = (char *) osip_malloc (port - ipv6host);
      if (via->host == NULL)
        return -1;
      osip_clrncpy (via->host, ipv6host + 1, port - ipv6host - 1);

      port = strchr (port, ':');
  } else
    {
      port = strchr (host, ':');
      ipv6host = NULL;
    }

  if ((port != NULL) && (port < via_params))
    {
      if (via_params - port < 2)
        return -1;
      via->port = (char *) osip_malloc (via_params - port);
      if (via->port == NULL)
        return -1;
      osip_clrncpy (via->port, port + 1, via_params - port - 1);
  } else
    port = via_params;

  /* host is already set in the case of ipv6 */
  if (ipv6host != NULL)
    return 0;

  if (port - host < 2)
    return -1;
  via->host = (char *) osip_malloc (port - host);
  if (via->host == NULL)
    return -1;
  osip_clrncpy (via->host, host + 1, port - host - 1);

  return 0;
}
예제 #17
0
/* return -1 on error */
int
osip_uri_parse (osip_uri_t * url, const char *buf)
{
  char *username;
  char *password;
  char *host;
  const char *port;
  const char *params;
  const char *headers;
  const char *tmp;

  /* basic tests */
  if (buf == NULL || buf[0] == '\0')
    return -1;

  tmp = strchr (buf, ':');
  if (tmp == NULL)
    return -1;

  if (tmp - buf < 2)
    return -1;
  url->scheme = (char *) osip_malloc (tmp - buf + 1);
  if (url->scheme == NULL)
    return -1;
  osip_strncpy (url->scheme, buf, tmp - buf);

  if (strlen (url->scheme) < 3 ||
      (0 != osip_strncasecmp (url->scheme, "sip", 3)
       && 0 != osip_strncasecmp (url->scheme, "sips", 4)))
    {                           /* Is not a sipurl ! */
      size_t i = strlen (tmp + 1);

      if (i < 2)
        return -1;
      url->string = (char *) osip_malloc (i + 1);
      if (url->string == NULL)
        return -1;
      osip_strncpy (url->string, tmp + 1, i);
      return 0;
    }

  /*  law number 1:
     if ('?' exists && is_located_after '@')
     or   if ('?' exists && '@' is not there -no username-)
     =====>  HEADER_PARAM EXIST
     =====>  start at index(?)
     =====>  end at the end of url
   */

  /* find the beginning of host */
  username = strchr (buf, ':');
  /* if ':' does not exist, the url is not valid */
  if (username == NULL)
    return -1;

  host = strchr (buf, '@');

  if (host == NULL)
    host = username;
  else if (username[1] == '@')  /* username is empty */
    host = username + 1;
  else
    /* username exists */
    {
      password = next_separator (username + 1, ':', '@');
      if (password == NULL)
        password = host;
      else
        /* password exists */
        {
          if (host - password < 2)
            return -1;
          url->password = (char *) osip_malloc (host - password);
          if (url->password == NULL)
            return -1;
          osip_strncpy (url->password, password + 1, host - password - 1);
          __osip_uri_unescape (url->password);
        }
      if (password - username < 2)
        return -1;
      {
        url->username = (char *) osip_malloc (password - username);
        if (url->username == NULL)
          return -1;
        osip_strncpy (url->username, username + 1, password - username - 1);
        __osip_uri_unescape (url->username);
      }
    }


  /* search for header after host */
  headers = strchr (host, '?');

  if (headers == NULL)
    headers = buf + strlen (buf);
  else
    /* headers exist */
    osip_uri_parse_headers (url, headers);


  /* search for params after host */
  params = strchr (host, ';');  /* search for params after host */
  if (params == NULL)
    params = headers;
  else
    /* params exist */
    {
      char *tmpbuf;

      if (headers - params + 1 < 2)
        return -1;
      tmpbuf = osip_malloc (headers - params + 1);
      if (tmpbuf == NULL)
        return -1;
      tmpbuf = osip_strncpy (tmpbuf, params, headers - params);
      osip_uri_parse_params (url, tmpbuf);
      osip_free (tmpbuf);
    }

  port = params - 1;
  while (port > host && *port != ']' && *port != ':')
    port--;
  if (*port == ':')
    {
      if (host == port)
        port = params;
      else
        {
          if ((params - port < 2) || (params - port > 8))
            return -1;          /* error cases */
          url->port = (char *) osip_malloc (params - port);
          if (url->port == NULL)
            return -1;
          osip_clrncpy (url->port, port + 1, params - port - 1);
        }
  } else
    port = params;
  /* adjust port for ipv6 address */
  tmp = port;
  while (tmp > host && *tmp != ']')
    tmp--;
  if (*tmp == ']')
    {
      port = tmp;
      while (host < port && *host != '[')
        host++;
      if (host >= port)
        return -1;
    }

  if (port - host < 2)
    return -1;
  url->host = (char *) osip_malloc (port - host);
  if (url->host == NULL)
    return -1;
  osip_clrncpy (url->host, host + 1, port - host - 1);

  return 0;
}
예제 #18
0
int
osip_message_set_multiple_header (osip_message_t * sip, char *hname, char *hvalue)
{
  int i;
  char *ptr, *p;                /* current location of the search */
  char *comma;                  /* This is the separator we are elooking for */
  char *beg;                    /* beg of a header */
  char *end;                    /* end of a header */
  int inquotes, inuri;          /* state for inside/outside of double-qoutes or URI */
  size_t hname_len;

  /* Find header based upon lowercase comparison */
  osip_tolower (hname);

  if (hvalue == NULL) {
    i = osip_message_set__header (sip, hname, hvalue);
    if (i != 0)
      return i;
    return OSIP_SUCCESS;
  }

  ptr = hvalue;
  comma = strchr (ptr, ',');

  hname_len = strlen (hname);

  if (comma == NULL || (hname_len == 4 && strncmp (hname, "date", 4) == 0)
      || (hname_len == 1 && strncmp (hname, "t", 1) == 0)
      || (hname_len == 2 && strncmp (hname, "to", 2) == 0)
      || (hname_len == 1 && strncmp (hname, "f", 1) == 0)
      || (hname_len == 4 && strncmp (hname, "from", 4) == 0)
      || (hname_len == 1 && strncmp (hname, "i", 1) == 0)
      || (hname_len == 7 && strncmp (hname, "call-id", 7) == 0)
      || (hname_len == 4 && strncmp (hname, "cseq", 4) == 0)
      || (hname_len == 1 && strncmp (hname, "s", 1) == 0)
      || (hname_len == 7 && strncmp (hname, "subject", 7) == 0)
      || (hname_len == 7 && strncmp (hname, "expires", 7) == 0)
      || (hname_len == 6 && strncmp (hname, "server", 6) == 0)
      || (hname_len == 10 && strncmp (hname, "user-agent", 10) == 0)
      || (hname_len == 16 && strncmp (hname, "www-authenticate", 16) == 0)
      || (hname_len == 19 && strncmp (hname, "authentication-info", 19) == 0)
      || (hname_len == 18 && strncmp (hname, "proxy-authenticate", 18) == 0)
      || (hname_len == 19 && strncmp (hname, "proxy-authorization", 19) == 0)
      || (hname_len == 25 && strncmp (hname, "proxy-authentication-info", 25) == 0)
      || (hname_len == 12 && strncmp (hname, "organization", 12) == 0)
      || (hname_len == 13 && strncmp (hname, "authorization", 13) == 0)
      || (hname_len == 1 && strncmp (hname, "r", 1) == 0) /* refer-to */
      || (hname_len == 8 && strncmp (hname, "refer-to", 8) == 0)
      || (hname_len == 1 && strncmp (hname, "b", 1) == 0) /* referred-by */
      || (hname_len == 11 && strncmp (hname, "referred-by", 11) == 0))
    /* there is no multiple header! likely      */
    /* to happen most of the time...            */
    /* or hname is a TEXT-UTF8-TRIM and may     */
    /* contain a comma. this is not a separator */
    /* THIS DOES NOT WORK FOR UNKNOWN HEADER!!!! */
  {
    i = osip_message_set__header (sip, hname, hvalue);
    if (i != 0)
      return i;
    return OSIP_SUCCESS;
  }

  beg = hvalue;
  inquotes = 0;
  inuri = 0;
  /* Seach for a comma that is not within quotes or a URI */
  for (;; ptr++)
  {
    switch (*ptr)
    {
    case '"':
      /* Check that the '"' is not escaped */
      for (i = 0, p = ptr; p >= beg && *p == '\\'; p--, i++);
      if (i % 2 == 0)
        inquotes = !inquotes; /* the '"' was not escaped */
      break;

    case '<':
      if (!inquotes)
      {
        if (!inuri)
        {
          if((osip_strncasecmp(ptr+1, "sip:", 4) == 0
              || osip_strncasecmp(ptr+1, "sips:", 5) == 0
              || osip_strncasecmp(ptr+1, "http:", 5) == 0
              || osip_strncasecmp(ptr+1, "https:", 6) == 0
              || osip_strncasecmp(ptr+1, "tel:", 4) == 0)
              && strchr(ptr, '>'))
            inuri = 1;
        }
	/*
	  else {
	  if we found such sequence: "<sip:" "<sip:" ">"
	  It might be a valid header containing data and not URIs.
	  Thus, we ignore inuri
	  }
	*/
      }
      break;

    case '>':
      if (!inquotes)
      {
        if (inuri)
          inuri = 0;
      }
      break;

    case '\0':
      /* we discard any validation we tried: no valid uri detected */
      inquotes=0;
      inuri=0;
    case ',':
      if (!inquotes && !inuri)
      {
        char *avalue;

        if (beg[0] == '\0')
          return OSIP_SUCCESS; /* empty header */

        end = ptr;
        if (end - beg + 1 < 2)
	  {
	    beg=end+1;
	    break; /* skip empty header */
	  }
        avalue = (char *) osip_malloc (end - beg + 1);
        if (avalue==NULL)
          return OSIP_NOMEM;
        osip_clrncpy (avalue, beg, end - beg);
        /* really store the header in the sip structure */
        i = osip_message_set__header (sip, hname, avalue);
        osip_free (avalue);
        if (i != 0)
          return i;
        beg = end + 1;
      }
      if (*ptr == '\0')
        return OSIP_SUCCESS;
      break;

    default:
      break;
    }
  }
}