Beispiel #1
0
static void quote_forget(irc_t *irc, const char *channel, const char *user, list_t *list) {
    char *quotenick    = list_shift(list);
    char *quotemessage = list_shift(list);

    if (!quotenick || !quotemessage)
        return;
    if (!quote_access_check(irc, user))
        return;

    quote_nick_stripspecial(&quotenick);

    if (!quote_find(quotenick, quotemessage))
        return irc_write(irc, channel, "%s: Sorry, could not find any quotes like \"%s %s\"",
            user,
            quotenick,
            quotemessage
        );

    database_statement_t *statement = database_statement_create("DELETE FROM QUOTES WHERE NAME = ? AND CONTENT = ?");
    if (!database_statement_bind(statement, "ss", quotenick, quotemessage))
        return;
    if (!database_statement_complete(statement))
        return;

    irc_write(irc, channel, "%s: Ok, removed - \"%s %s..\" - from the quote db",
        user,
        quotenick,
        quotemessage
    );
}
Beispiel #2
0
static void quote_add(irc_t *irc, const char *channel, const char *user, list_t *list) {
    char *quotenick    = list_shift(list);
    char *quotemessage = list_shift(list);

    if (!quotenick || !quotemessage)
        return;
    if (!quote_access_check(irc, user))
        return;

    quote_nick_stripspecial(&quotenick);

    if (quote_find(quotenick, quotemessage))
        return irc_write(irc, channel, "%s: Quote already exists.", user);

    database_statement_t *statement = database_statement_create("INSERT INTO QUOTES (NAME, CONTENT) VALUES ( ?, ? )");
    if (!database_statement_bind(statement, "ss", quotenick, quotemessage))
        return;
    if (!database_statement_complete(statement))
        return;

    irc_write(irc, channel, "%s: Ok, added quote: <%s> %s", user, quotenick, quotemessage);
}
/* TODO:
   digest-challenge tken has no order preference??
   verify many situations (extra SP....)
*/
int
authorization_parse (authorization_t * auth, char *hvalue)
{
  char *space = NULL;
  char *next = NULL;

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

  if (space - hvalue < 1)
    return -1;
  auth->auth_type = (char *) smalloc (space - hvalue + 1);
  sstrncpy (auth->auth_type, hvalue, space - hvalue);

  for (;;)
    {
      int parse_ok = 0;

      if (quoted_string_set ("username", space, &(auth->username), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("realm", space, &(auth->realm), &next))
	return -1;
      if (next == NULL)
	return 0;
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("nonce", space, &(auth->nonce), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("uri", space, &(auth->uri), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("response", space, &(auth->response), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("digest", space, &(auth->digest), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (token_set ("algorithm", space, &(auth->algorithm), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("cnonce", space, &(auth->cnonce), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("opaque", space, &(auth->opaque), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (token_set ("qop", space, &(auth->message_qop), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (token_set ("nc", space, &(auth->nonce_count), &next))
	return -1;
      if (next == NULL)
	return 0;		/* 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)
	{
	  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 = quote_find (space);
	  if ((quote1 != NULL) && (quote1 < tmp))	/* this may be a quoted string! */
	    {
	      quote2 = 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
msg_handle_multiple_values (sip_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 */


  beg = hvalue;
  end = NULL;
  ptr = hvalue;
  if (hvalue == NULL)
    {
      i = msg_set_header (sip, hname, hvalue);
      if (i == -1)
	return -1;
      return 0;
    }

  comma = strchr (ptr, ',');


  stolowercase (hname);

  if (comma == NULL || (strncmp (hname, "date", 4) == 0 && strlen (hname) == 4 )
      || strncmp (hname, "organization", 12) == 0 || (strncmp (hname, "to", 2) == 0 && strlen (hname) == 2) || (strncmp (hname, "from", 4) == 0 && strlen (hname) == 4)	/* AMD: BUG fix */
      || strncmp (hname, "call-id", 7) == 0 || (strncmp (hname, "cseq", 4) == 0 && strlen (hname) == 4)	/* AMD: BUG fix */
      || strncmp (hname, "subject", 7) == 0 || strncmp (hname, "user-agent", 10) == 0 || strncmp (hname, "server", 6) == 0 || strncmp (hname, "www-authenticate", 16) == 0	/* AMD: BUG fix */
      || strncmp (hname, "authentication-info", 19) == 0 || strncmp (hname, "proxy-authenticate", 20) == 0 || strncmp (hname, "proxy-authorization", 19) == 0 || strncmp (hname, "proxy-authentication-info", 25) == 0	/* AMD: BUG fix */
      || 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 = msg_set_header (sip, hname, hvalue);
      if (i == -1)
	return -1;
      return 0;
    }

  quote2 = NULL;
  while (comma != NULL)
    {
      quote1 = quote_find (ptr);
      if (quote1 != NULL)
	{
	  quote2 = quote_find (quote1 + 1);
	  if (quote2 == NULL)
	    return -1;		/* quotes comes by pair */
	  ptr = quote2 + 1;
	}

      if ((quote1 == NULL) || (quote1 > comma))
	{
	  end = comma;
	  comma = strchr (comma + 1, ',');
	  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 (strlen (beg) < 2)
		return 0;	/* empty header */
	      sclrspace (beg);
	      i = msg_set_header (sip, hname, beg);
	      if (i == -1)
		return -1;
	      return 0;
	    }
	}

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

	  if (end - beg + 1 < 2)
	    return -1;
	  avalue = (char *) smalloc (end - beg + 1);
	  sstrncpy (avalue, beg, end - beg);
	  sclrspace (avalue);
	  /* really store the header in the sip structure */
	  i = msg_set_header (sip, hname, avalue);
	  sfree (avalue);
	  if (i == -1)
	    return -1;
	  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 (strlen (beg) < 2)
		return 0;	/* empty header */
	      sclrspace (beg);
	      i = msg_set_header (sip, hname, beg);
	      if (i == -1)
		return -1;
	      return 0;
	    }
	}
    }
  return -1;			/* if comma is NULL, we should have already return 0 */
}
int
quoted_string_set (char *name, char *str, char **result, char **next)
{
  *next = str;
  if (*result != NULL)
    return 0;			/* already parsed */
  *next = NULL;
  while ((' ' == *str) || ('\t' == *str) || (',' == *str))
    if (*str)
      str++;
    else
      return -1;		/* bad header format */

  if (strlen (str) <= strlen (name))
    return -1;			/* bad header format... */
#if (!defined WIN32 && !defined _WIN32_WCE)
  if (strncasecmp (name, str, strlen (name)) == 0)
#else
  if (_strnicmp (name, str, strlen (name)) == 0)
#endif
    {
      char *quote1;
      char *quote2;
      char *tmp;
      char *hack = strchr (str, '=');

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

      quote1 = quote_find (str);
      if (quote1 == NULL)
	return -1;		/* bad header format... */
      quote2 = quote_find (quote1 + 1);
      if (quote2 == NULL)
	return -1;		/* 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 0;
	  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 0;
	      *next = tmp;
	    }
	  return 0;
	}
      *result = (char *) smalloc (quote2 - quote1 + 3);
      if (*result == NULL)
	return -1;
      sstrncpy (*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 0;
      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 0;
	  *next = tmp;
	}
    }
  else
    *next = str;		/* wrong header asked! */
  return 0;
}
/* TODO:
   digest-challenge tken has no order preference??
   verify many situations (extra SP....)
*/
int
www_authenticate_parse (www_authenticate_t * wwwa, char *hvalue)
{
  char *space = NULL;
  char *next = NULL;

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

  if (space - hvalue + 1 < 2)
    return -1;
  wwwa->auth_type = (char *) smalloc (space - hvalue + 1);
  if (wwwa->auth_type == NULL)
    return -1;
  sstrncpy (wwwa->auth_type, hvalue, space - hvalue);

  for (;;)
    {
      int parse_ok = 0;

      if (quoted_string_set ("realm", space, &(wwwa->realm), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("domain", space, &(wwwa->domain), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("nonce", space, &(wwwa->nonce), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("opaque", space, &(wwwa->opaque), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (token_set ("stale", space, &(wwwa->stale), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (token_set ("algorithm", space, &(wwwa->algorithm), &next))
	return -1;
      if (next == NULL)
	return 0;		/* end of header detected! */
      else if (next != space)
	{
	  space = next;
	  parse_ok++;
	}
      if (quoted_string_set ("qop", space, &(wwwa->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 = quote_find (space);
	  if ((quote1 != NULL) && (quote1 < tmp))	/* this may be a quoted string! */
	    {
	      quote2 = 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 */
}