/* TODO:
   digest-challenge tken has no order preference??
   verify many situations (extra SP....)
*/
int
osip_authorization_parse (osip_authorization_t * auth, const char *hvalue)
{
  const char *space;
  const char *next = NULL;
  int i;

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

  if (space - hvalue < 1)
    return OSIP_SYNTAXERROR;
  auth->auth_type = (char *) osip_malloc (space - hvalue + 1);
  if (auth->auth_type==NULL)
	  return OSIP_NOMEM;
  osip_strncpy (auth->auth_type, hvalue, space - hvalue);

  for (;;)
    {
      int parse_ok = 0;

	  i = __osip_quoted_string_set ("username", space, &(auth->username), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("realm", space, &(auth->realm), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("nonce", space, &(auth->nonce), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("uri", space, &(auth->uri), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("response", space, &(auth->response), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("digest", space, &(auth->digest), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_token_set ("algorithm", space, &(auth->algorithm), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("cnonce", space, &(auth->cnonce), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_quoted_string_set ("opaque", space, &(auth->opaque), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_token_set ("qop", space, &(auth->message_qop), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      i = __osip_token_set ("nc", space, &(auth->nonce_count), &next);
      if (i!=0)
        return i;
      if (next == NULL)
        return OSIP_SUCCESS;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      /* nothing was recognized:
         here, we should handle a list of unknown tokens where:
         token1 = ( token2 | quoted_text ) */
      /* TODO */

      if (0 == parse_ok)
        {
          const char *quote1, *quote2, *tmp;

          /* CAUTION */
          /* parameter not understood!!! I'm too lazy to handle IT */
          /* let's simply bypass it */
          if (strlen (space) < 1)
            return OSIP_SUCCESS;
          tmp = strchr (space + 1, ',');
          if (tmp == NULL)      /* it was the last header */
            return OSIP_SUCCESS;
          quote1 = __osip_quote_find (space);
          if ((quote1 != NULL) && (quote1 < tmp))       /* this may be a quoted string! */
            {
              quote2 = __osip_quote_find (quote1 + 1);
              if (quote2 == NULL)
                return OSIP_SYNTAXERROR;      /* bad header format... */
              if (tmp < quote2) /* the comma is inside the quotes! */
                space = strchr (quote2, ',');
              else
                space = tmp;
              if (space == NULL)        /* it was the last header */
                return OSIP_SUCCESS;
          } else
            space = tmp;
          /* continue parsing... */
        }
    }
  return OSIP_SUCCESS;                     /* ok */
}
int
__osip_quoted_string_set (const char *name, const char *str, char **result, const char **next)
{
  *next = str;
  if (*result != NULL)
    return OSIP_SUCCESS;        /* already parsed */
  *next = NULL;
  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 *quote1;
    const char *quote2;
    const char *tmp;
    const char *hack = strchr (str, '=');

    if (hack == NULL)
      return OSIP_SYNTAXERROR;

    while (' ' == *(hack - 1))  /* get rid of extra spaces */
      hack--;
    if ((size_t) (hack - str) != strlen (name)) {
      *next = str;
      return OSIP_SUCCESS;
    }

    quote1 = __osip_quote_find (str);
    if (quote1 == NULL)
      return OSIP_SYNTAXERROR;  /* bad header format... */
    quote2 = __osip_quote_find (quote1 + 1);
    if (quote2 == NULL)
      return OSIP_SYNTAXERROR;  /* bad header format... */
    if (quote2 - quote1 == 1) {
      /* this is a special case! The quote contains nothing! */
      /* example:   Digest opaque="",cnonce=""               */
      /* in this case, we just forget the parameter... this  */
      /* this should prevent from user manipulating empty    */
      /* strings */
      tmp = quote2 + 1;         /* next element start here */
      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;
      }
      return OSIP_SUCCESS;
    }
    *result = (char *) osip_malloc (quote2 - quote1 + 3);
    if (*result == NULL)
      return OSIP_NOMEM;
    osip_strncpy (*result, quote1, quote2 - quote1 + 1);
    tmp = quote2 + 1;           /* next element start here */
    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;                /* wrong header asked! */
  return OSIP_SUCCESS;
}
/* TODO:
   digest-challenge tken has no order preference??
   verify many situations (extra SP....)
*/
int
osip_www_authenticate_parse (osip_www_authenticate_t * wwwa, const char *hvalue)
{
  const char *space;
  const char *next = NULL;
  int i;

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

  if (space - hvalue + 1 < 2)
    return OSIP_SYNTAXERROR;
  wwwa->auth_type = (char *) osip_malloc (space - hvalue + 1);
  if (wwwa->auth_type == NULL)
    return OSIP_NOMEM;
  osip_strncpy (wwwa->auth_type, hvalue, space - hvalue);

  for (;;) {
    int parse_ok = 0;

    i = __osip_quoted_string_set ("realm", space, &(wwwa->realm), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_quoted_string_set ("domain", space, &(wwwa->domain), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_quoted_string_set ("nonce", space, &(wwwa->nonce), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_quoted_string_set ("opaque", space, &(wwwa->opaque), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_token_set ("stale", space, &(wwwa->stale), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_token_set ("algorithm", space, &(wwwa->algorithm), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_quoted_string_set ("qop", space, &(wwwa->qop_options), &next);
    if (i != 0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;      /* end of header detected! */
    else if (next != space) {
      space = next;
      parse_ok++;
    }
    i = __osip_token_set ("version", space, &(wwwa->version), &next);
    if (i!=0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;               /* end of header detected! */
    else if (next != space)
      {
        space = next;
        parse_ok++;
      }
       i = __osip_quoted_string_set ("targetname", space, &(wwwa->targetname), &next);
    if (i!=0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;               /* end of header detected! */
    else if (next != space)
      {
        space = next;
        parse_ok++;
      }
       i = __osip_quoted_string_set ("gssapi-data", space, &(wwwa->gssapi_data), &next);
    if (i!=0)
      return i;
    if (next == NULL)
      return OSIP_SUCCESS;               /* end of header detected! */
    else if (next != space)
      {
        space = next;
        parse_ok++;
      }
    if (0 == parse_ok) {
      const char *quote1, *quote2, *tmp;

      /* CAUTION */
      /* parameter not understood!!! I'm too lazy to handle IT */
      /* let's simply bypass it */
      if (strlen (space) < 1)
        return OSIP_SUCCESS;
      tmp = strchr (space + 1, ',');
      if (tmp == NULL)          /* it was the last header */
        return OSIP_SUCCESS;
      quote1 = __osip_quote_find (space);
      if ((quote1 != NULL) && (quote1 < tmp)) { /* this may be a quoted string! */
        quote2 = __osip_quote_find (quote1 + 1);
        if (quote2 == NULL)
          return OSIP_SYNTAXERROR;      /* bad header format... */
        if (tmp < quote2)       /* the comma is inside the quotes! */
          space = strchr (quote2, ',');
        else
          space = tmp;
        if (space == NULL)      /* it was the last header */
          return OSIP_SUCCESS;
      }
      else
        space = tmp;
      /* continue parsing... */
    }
  }
  return OSIP_SUCCESS;          /* ok */
}
/* TODO:
   digest-challenge tken has no order preference??
   verify many situations (extra SP....)
*/
int
osip_authentication_info_parse (osip_authentication_info_t * ainfo,
                                const char *hvalue)
{
  const char *space;
  const char *next = NULL;

  space = hvalue;

  for (;;)
    {
      int parse_ok = 0;

      if (__osip_quoted_string_set
          ("nextnonce", space, &(ainfo->nextnonce), &next))
        return -1;
      if (next == NULL)
        return 0;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      if (__osip_quoted_string_set ("cnonce", space, &(ainfo->cnonce), &next))
        return -1;
      if (next == NULL)
        return 0;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      if (__osip_quoted_string_set ("rspauth", space, &(ainfo->rspauth), &next))
        return -1;
      if (next == NULL)
        return 0;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      if (__osip_token_set ("nc", space, &(ainfo->nonce_count), &next))
        return -1;
      if (next == NULL)
        return 0;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      if (__osip_token_set ("qop", space, &(ainfo->qop_options), &next))
        return -1;
      if (next == NULL)
        return 0;               /* end of header detected! */
      else if (next != space)
        {
          space = next;
          parse_ok++;
        }
      if (0 == parse_ok)
        {
          char *quote1, *quote2, *tmp;

          /* CAUTION */
          /* parameter not understood!!! I'm too lazy to handle IT */
          /* let's simply bypass it */
          if (strlen (space) < 1)
            return 0;
          tmp = strchr (space + 1, ',');
          if (tmp == NULL)      /* it was the last header */
            return 0;
          quote1 = __osip_quote_find (space);
          if ((quote1 != NULL) && (quote1 < tmp))       /* this may be a quoted string! */
            {
              quote2 = __osip_quote_find (quote1 + 1);
              if (quote2 == NULL)
                return -1;      /* bad header format... */
              if (tmp < quote2) /* the comma is inside the quotes! */
                space = strchr (quote2, ',');
              else
                space = tmp;
              if (space == NULL)        /* it was the last header */
                return 0;
          } else
            space = tmp;
          /* continue parsing... */
        }
    }
  return 0;                     /* ok */
}
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 */
}
Beispiel #6
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;
}