Ejemplo n.º 1
0
/* clean_host()
 *
 * input	- host to check
 * output	- 0 if erroneous, else 0
 * side effects -
 */
static int
clean_host(const char *host)
{
	int len = 0;
	const char *last_slash = 0;
	
	if (*host == '\0' || *host == ':')
		return 0;

	for(; *host; host++)
	{
		len++;

		if(!IsHostChar(*host))
			return 0;
		if(*host == '/')
			last_slash = host;
	}

	if(len > HOSTLEN)
		return 0;

	if(last_slash && IsDigit(last_slash[1]))
		return 0;

	return 1;
}
Ejemplo n.º 2
0
/* 
 * valid_hostname - check hostname for validity
 *
 * Inputs	- pointer to user
 * Output	- YES if valid, NO if not
 * Side effects - NONE
 *
 * NOTE: this doesn't allow a hostname to begin with a dot and
 * will not allow more dots than chars.
 */
bool
valid_hostname(const char *hostname)
{
	const char *p = hostname;
	int found_sep = 0;

	s_assert(NULL != p);

	if(hostname == NULL)
		return false;

	if('.' == *p || ':' == *p)
		return false;

	while(*p)
	{
		if(!IsHostChar(*p))
			return false;
		if(*p == '.' || *p == ':')
			found_sep++;
		p++;
	}

	if(found_sep == 0)
		return (false);

	return (true);
}
Ejemplo n.º 3
0
/* 
 * valid_hostname - check hostname for validity
 *
 * Inputs       - pointer to user
 * Output       - 1 for valid, 0 for invalid
 *
 * NOTE: this doesn't allow a hostname to begin with a dot and
 * will not allow more dots than chars.
 */
int irc_IsValidHostname(const char* hostname)
{
  int         dots  = 0;
  int         chars = 0;
  const char* p     = hostname;

  assert(0 != p);

  if ('.' == *p)
    return 0;

  while (*p) {
    if (!IsHostChar(*p))
      return 0;
    if ('.' == *p || ':' == *p)
    {
      ++p;
      ++dots;
    }
    else
    {
      ++p;
      ++chars;
    }
  }
  return ( 0 == dots || chars < dots) ? 0 : 1;
}
Ejemplo n.º 4
0
u_short
check_hm(user_t *cptr, char *hm)
{
	if (strlen(hm) > HOSTLEN)
		return (cptr ? reply(OS, cptr->nick, "The hostmask is too long.") : 1);
	for (; *hm; hm++)
		if (!IsHostChar(*hm) && *hm != '*' && *hm != '?')
			return (cptr ? reply(OS, cptr->nick, "The character '%c' is not allowed in your hostmask.", *hm) : 1);
	return 0;
}
Ejemplo n.º 5
0
int ValidateHostWild( const char *hostname )
{
	if( hostname == NULL )
		return NS_FAILURE;
	while( *hostname != '\0' )
	{
		if( !IsHostChar( *hostname ) && !IsWildChar( *hostname ) )
			return NS_FAILURE;
		hostname++;
	}
	return NS_SUCCESS;
}
Ejemplo n.º 6
0
/* auth_verify_hostname - verify that a hostname is valid, i.e., only
 * contains characters valid for a hostname and that a hostname is not
 * too long.
 */
static int auth_verify_hostname(char *host, int maxlen)
{
  int i;

  /* Walk through the host name */
  for (i = 0; host[i]; i++)
    /* If it's not a hostname character or if it's too long, return false */
    if (!IsHostChar(host[i]) || i >= maxlen)
      return 0;

  return 1; /* it's a valid hostname */
}
Ejemplo n.º 7
0
u_short
check_host(user_t *cptr, char *hm)
{
	if (strlen(hm) > HOSTLEN)
		return (cptr ? reply(OS, cptr->nick, "Your host is too long.") : 1);
	if (!strchr(hm, '.'))
		return (cptr ? reply(OS, cptr->nick, "Your host must contain at least one period.") : 1);
	for (; *hm; hm++)
		if (!IsHostChar(*hm))
			return (cptr ? reply(OS, cptr->nick, "The %s '%c' is not allowed in your hostmask.", ((*hm == '*' || *hm == '?') ? "wildcard" : "character"), *hm) : 1);
	return 0;
}
Ejemplo n.º 8
0
/* clean_host_name()
 * input	- hostname
 * output	- none
 * side effects - walks through the hostname, returning 0 if erroneous
 */
static int
clean_host_name(const char *host)
{
  const char *p = host;

  assert(host && *host);

  for (; *p; ++p)
    if (!IsHostChar(*p))
      return 0;

  return p - host <= HOSTLEN;
}
Ejemplo n.º 9
0
int ValidateHost( const char *hostname )
{
	if( hostname == NULL )
		return NS_FAILURE;
	if( !strchr( hostname, '.' ) )
		return NS_FAILURE;
	while( *hostname != '\0' )
	{
		if( !IsHostChar( *hostname ) )
			return NS_FAILURE;
		hostname++;
	}
	return NS_SUCCESS;
}
Ejemplo n.º 10
0
/* clean_host_name()
 * input	- hostname
 * output	- none
 * side effects - walks through the hostname, returning 0 if erroneous
 */
static int
clean_host_name(char *host)
{
	s_assert(host);
	if(host == NULL)
		return 0;
	for (; *host; host++)
	{
		if(!IsHostChar(*host))
			return 0;
	}

	return 1;
}
Ejemplo n.º 11
0
static int
clean_host(const char *host)
{
    int len = 0;

    for (; *host; host++) {
        len++;

        if(!IsHostChar(*host))
            return 0;
    }

    if(len > HOSTLEN)
        return 0;

    return 1;
}
Ejemplo n.º 12
0
static int
invalid_hostname(const char *hostname)
{
  const char *p = hostname;
  unsigned int has_sep = 0;

  assert(p != NULL);

  if (*p == '.' || *p == ':')
    return 1;

  for (; *p; ++p)
  {
    if (!IsHostChar(*p))
      return 1;
    if (*p == '.' || *p == ':')
      ++has_sep;
  }

  return !has_sep;
}
Ejemplo n.º 13
0
static void
mo_spoof(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
  char *host, *spoof, *password;
  const char *tmp = NULL;
  const char *user = NULL;
  const char *flags = NULL;
  int i = 0;
#ifdef SPOOF_FILE
  int class_opers;
  FBFILE *f;
  char buffer[1024];
  struct AddressRec *arec;
#endif

  if (MyConnect(source_p) && !IsOperAdmin(source_p))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "SPOOF");
    return;
  }

  /* check the user@host mask */
  if (strchr(parv[1], '!') != NULL)
  {
    syntax:
    if (MyConnect(source_p))
      sendto_one(source_p, ":%s NOTICE %s :Syntax: SPOOF <umask@hmask> "
                 "<spoof/-> [flags/- [password]]", me.name, source_p->name);
    return;
  }

  (void) collapse(parv[1]);

  for (tmp = parv[1]; *tmp; tmp++)
    if (!IsKWildChar(*tmp))
      if (++i >= ConfigFileEntry.min_nonwildcard)
        break;
  if (i < ConfigFileEntry.min_nonwildcard)
  {
    if (MyConnect(source_p))
      sendto_one(source_p, ":%s NOTICE %s :Not enough non-wildcard characters "
                           "in user@host mask",
                           me.name, source_p->name);
    return;
  }

  host = strchr(parv[1], '@');
  if (host)
  {
    user = parv[1];
    *host = '\0';
    host++;
  }
  else
  {
    user = "******";
    host = parv[1];
  }

  /* check the spoof field */
  spoof = parv[2];
  if (spoof == NULL || !*spoof)
    goto syntax;

  if (spoof[0] != '-' || spoof[1] != '\0')
  {
    for (tmp = spoof; *tmp; tmp++)
      if (!IsHostChar(*tmp)) {
        if (MyConnect(source_p))
          sendto_one(source_p, ":%s NOTICE %s :The spoof [%s] is invalid",
                     me.name, source_p->name, spoof);
        return;
      }
    if (strlen(spoof) >= HOSTLEN) {
      if (MyConnect(source_p))
        sendto_one(source_p, ":%s NOTICE %s :Spoofs must be less than %d.."
                             "ignoring it", me.name, source_p->name, HOSTLEN);
      return;
    }
  }

  flags = (parc > 3) ? parv[3] : "-";
  password = (parc > 4 && parv[4][0]) ? parv[4] : NULL;

#ifdef PROPAGATE_SPOOF
  sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT,
                ":%s SPOOF %s@%s %s %s :%s",
                source_p->name, user, host, spoof, flags, password ? password : "");
#endif

#ifdef SPOOF_FILE
  /* Walk through auth {} items and check if we have another auth block
   * for this hostname */
  for (i = 0; i < ATABLE_SIZE; i++)
    for (arec = atable[i]; arec; arec = arec->next)
      if (arec->type == CONF_CLIENT && !irccmp(arec->aconf->host, host) &&
        !irccmp(arec->aconf->user, user))
      {
        /* auth entry already exists */
        if (MyConnect(source_p))
          sendto_one(source_p,
                     ":%s NOTICE %s :auth for %s@%s already exists, you need "
                     "to use /DELSPOOF first", me.name, source_p->name, user, host);
#ifdef LOG_SPOOF
        sendto_realops_flags(UMODE_ALL, L_ALL,
                             "%s attemped to re-add auth for %s@%s "
                             "[spoof: %s, flags: %s]", source_p->name, user, host,
                             spoof, flags);
#endif
        return;
      }

  /* Add the spoof to the the spoof file */
  if ((f = fbopen(SPOOF_FILE, "a")) == NULL)
  {
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "Could not open %s file, auth for %s@%s "
                         "[spoof: %s, flags: %s, requested by %s] not added",
                         SPOOF_FILE, user, host, spoof, flags, source_p->name);
    return;
  }

  /* write the auth {} block */
  fbputs("auth {\n", f, 7);
  i = ircsprintf(buffer, "\tuser = \"%s@%s\";\n", user, host);
  fbputs(buffer, f, i);
  if (spoof[0] != '-' || spoof[1] != '\0')
  {
    i = ircsprintf(buffer, "\tspoof = \"%s\";\n", spoof);
    fbputs(buffer, f, i);
  }
  if (password)
  {
    i = ircsprintf(buffer, "\tpassword = \"%s\";\n", password);
    fbputs(buffer, f, i);
  }

  /* process given flags */
  i = class_opers = 0;
  for (tmp = flags; *tmp; ++tmp)
    switch (*tmp)
    {
      case 't': i |= CONF_FLAGS_NO_TILDE;      /* no_tilde = yes; */
                break;
      case 'i': i |= CONF_FLAGS_NEED_IDENTD;   /* need_ident = yes; */
                break;
      case 'k': i |= CONF_FLAGS_EXEMPTKLINE;   /* kline_exempt = yes; */
                break;
      case 'g': i |= CONF_FLAGS_EXEMPTGLINE;   /* gline_exempt = yes; */
                break;
      case 'l': i |= CONF_FLAGS_NOLIMIT;       /* exceed_limit = yes; */
                break;
      case 'o': class_opers = 1;               /* class = "opers"; */
                break;
      case 'f': i |= CONF_FLAGS_CAN_FLOOD;     /* can_flood = yes; */
                break;
      case 'p': i|= CONF_FLAGS_NEED_PASSWORD;  /* need_password = yes; */
    }

  if (i)
  {
    fbputs("\tflags = ", f, 9);
    try_flag(f, &i, CONF_FLAGS_NO_TILDE, "no_tilde");
    try_flag(f, &i, CONF_FLAGS_NEED_IDENTD, "need_ident");
    try_flag(f, &i, CONF_FLAGS_EXEMPTKLINE, "kline_exempt");
    try_flag(f, &i, CONF_FLAGS_EXEMPTGLINE, "gline_exempt");
    try_flag(f, &i, CONF_FLAGS_NOLIMIT, "exceed_limit");
    try_flag(f, &i, CONF_FLAGS_CAN_FLOOD, "can_flood");
    try_flag(f, &i, CONF_FLAGS_NEED_PASSWORD, "need_password");
  }

  if (class_opers)
    fbputs("\tclass = \"opers\";\n", f, 18);
  else
    fbputs("\tclass = \"users\";\n", f, 18);

  fbputs("};\n\n", f, 4);
  fbclose(f);

  rehash(0);
#endif

#ifdef LOG_SPOOF
  sendto_realops_flags(UMODE_ALL, L_ALL,
                       "%s added auth for %s@%s [spoof: %s, flags: %s]",
                       source_p->name, user, host, spoof, flags);
  ilog(L_TRACE, "%s added auth for %s@%s [spoof: %s, flags: %s]",
                source_p->name, user, host, spoof, flags);
#endif
}
Ejemplo n.º 14
0
static void
check_new_user(void *vdata)
{
	struct Client *source_p = (void *)vdata;

	if (!IsIPSpoof(source_p))
		return;

	if (EmptyString(source_p->user->suser))
		return;

	char *accountpart = strstr(source_p->orighost, "account");
	if (!accountpart)
		return;

	char buf[HOSTLEN];
	memset(buf, 0, sizeof(buf));
	char *dst = buf;

	strncpy(buf, source_p->orighost, accountpart - source_p->orighost);
	dst += accountpart - source_p->orighost;

	int needhash = 0;

	for (char *src = source_p->user->suser; *src ; src++ )
	{
		if (dst > buf + sizeof(buf))
		{
			/* Doesn't fit. Warn opers and bail. */
			sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
					"Couldn't fit account name part %s in hostname for %s!%s@%s",
					source_p->user->suser, source_p->name, source_p->username, source_p->orighost);
			return;
		}

		char c = ToLower(*src);

		if (IsHostChar(c))
			*dst++ = c;
		else
			needhash = 1;
	}

	if (needhash)
	{
		if (dst > buf + sizeof(buf) - 12) /* '/x-' plus eight digit hash plus null terminator */
		{
			/* Doesn't fit. Warn opers and bail. */
			sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
					"Couldn't fit account name part %s in hostname for %s!%s@%s",
					source_p->user->suser, source_p->name, source_p->username, source_p->orighost);
			return;
		}

		*dst++ = '/';
		*dst++ = 'x';
		*dst++ = '-';

		unsigned int hashval = fnv_hash_string(source_p->user->suser);
		hashval %= 100000000; // eight digits only please.
		snprintf(dst, 9, "%08ud", hashval);
	}

	/* just in case */
	buf[HOSTLEN-1] = '\0';

	/* If hostname has been changed already (probably by services cloak on SASL login), then
	 * leave it intact. If not, change it. In either case, update the original hostname.
	 */
	if (0 == irccmp(source_p->host, source_p->orighost))
		change_nick_user_host(source_p, source_p->name, source_p->username, buf, 0, "Changing host");
	strncpy(source_p->orighost, buf, HOSTLEN);
}
Ejemplo n.º 15
0
int eval_host_char(char c)
{
  return (0 != IsHostChar(c));
}