Exemple #1
0
static int
accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
{
	struct Listener *listener = (struct Listener *)data;
	char buf[BUFSIZE];
	struct ConfItem *aconf;
	static time_t last_oper_notice = 0;
	int len;

	if(listener->ssl && (!ssl_ok || !get_ssld_count()))
	{
		rb_close(F);
		return 0;
	}

	if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus */
	{
		++ServerStats.is_ref;
		/*
		 * slow down the whining to opers bit
		 */
		if((last_oper_notice + 20) <= rb_current_time())
		{
			sendto_realops_snomask(SNO_GENERAL, L_ALL,
					     "All connections in use. (%s)",
					     get_listener_name(listener));
			last_oper_notice = rb_current_time();
		}

		rb_write(F, "ERROR :All connections in use\r\n", 32);
		rb_close(F);
		return 0;
	}

	aconf = find_dline(addr, addr->sa_family);
	if(aconf != NULL && (aconf->status & CONF_EXEMPTDLINE))
		return 1;

	/* Do an initial check we aren't connecting too fast or with too many
	 * from this IP... */
	if(aconf != NULL)
	{
		ServerStats.is_ref++;

		if(ConfigFileEntry.dline_with_reason)
		{
			len = rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf));
			if (len >= (int)(sizeof(buf)-1))
			{
				buf[sizeof(buf) - 3] = '\r';
				buf[sizeof(buf) - 2] = '\n';
				buf[sizeof(buf) - 1] = '\0';
			}
		}
		else
			strcpy(buf, "ERROR :You have been D-lined.\r\n");

		rb_write(F, buf, strlen(buf));
		rb_close(F);
		return 0;
	}

	if(check_reject(F, addr))
		return 0;

	if(throttle_add(addr))
	{
		rb_write(F, toofast, strlen(toofast));
		rb_close(F);
		return 0;
	}

	return 1;
}
static int
mo_testline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    struct ConfItem *aconf;
    struct ConfItem *resv_p;
    struct sockaddr_storage ip;
    char user_trunc[USERLEN + 1], notildeuser_trunc[USERLEN + 1];
    const char *name = NULL;
    const char *username = NULL;
    const char *host = NULL;
    char *mask;
    char *p;
    int host_mask;
    int type;
    int duration;
    char *puser, *phost, *reason, *operreason;
    char reasonbuf[BUFSIZE];

    mask = LOCAL_COPY(parv[1]);

    if (IsChannelName(mask)) {
        resv_p = hash_find_resv(mask);
        if (resv_p != NULL) {
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       resv_p->hold ? 'q' : 'Q',
                       resv_p->hold ? (long) ((resv_p->hold - rb_current_time()) / 60) : 0L,
                       resv_p->host, resv_p->passwd);
            /* this is a false positive, so make sure it isn't counted in stats q
             * --nenolod
             */
            resv_p->port--;
        } else
            sendto_one(source_p, form_str(RPL_NOTESTLINE),
                       me.name, source_p->name, parv[1]);
        return 0;
    }

    if((p = strchr(mask, '!'))) {
        *p++ = '\0';
        name = mask;
        mask = p;

        if(EmptyString(mask))
            return 0;
    }

    if((p = strchr(mask, '@'))) {
        *p++ = '\0';
        username = mask;
        host = p;

        if(EmptyString(host))
            return 0;
    } else
        host = mask;

    /* parses as an IP, check for a dline */
    if((type = parse_netmask(host, (struct sockaddr *)&ip, &host_mask)) != HM_HOST) {
#ifdef RB_IPV6
        if(type == HM_IPV6)
            aconf = find_dline((struct sockaddr *)&ip, AF_INET6);
        else
#endif
            aconf = find_dline((struct sockaddr *)&ip, AF_INET);

        if(aconf && aconf->status & CONF_DLINE) {
            get_printable_kline(source_p, aconf, &phost, &reason, &puser, &operreason);
            snprintf(reasonbuf, sizeof(reasonbuf), "%s%s%s", reason,
                        operreason ? "|" : "", operreason ? operreason : "");
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'd' : 'D',
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ?
                       (long) ((aconf->hold - rb_current_time()) / 60) : 0L,
                       phost, reasonbuf);

            return 0;
        }
        /* Otherwise, aconf is an exempt{} */
        if(aconf == NULL &&
           (duration = is_reject_ip((struct sockaddr *)&ip)))
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       '!',
                       duration / 60,
                       host, "Reject cache");
        if(aconf == NULL &&
           (duration = is_throttle_ip((struct sockaddr *)&ip)))
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       '!',
                       duration / 60,
                       host, "Throttled");
    }

    if (username != NULL) {
        rb_strlcpy(user_trunc, username, sizeof user_trunc);
        rb_strlcpy(notildeuser_trunc, *username == '~' ? username + 1 : username, sizeof notildeuser_trunc);
    } else {
        rb_strlcpy(user_trunc, "dummy", sizeof user_trunc);
        rb_strlcpy(notildeuser_trunc, "dummy", sizeof notildeuser_trunc);
    }
    /* now look for a matching I/K/G */
    if((aconf = find_address_conf(host, NULL, user_trunc, notildeuser_trunc,
                                  (type != HM_HOST) ? (struct sockaddr *)&ip : NULL,
                                  (type != HM_HOST) ? (
#ifdef RB_IPV6
                                      (type == HM_IPV6) ? AF_INET6 :
#endif
                                      AF_INET) : 0, NULL))) {
        static char buf[HOSTLEN+USERLEN+2];

        if(aconf->status & CONF_KILL) {
            get_printable_kline(source_p, aconf, &phost, &reason, &puser, &operreason);
            snprintf(buf, sizeof(buf), "%s@%s",
                        puser, phost);
            snprintf(reasonbuf, sizeof(reasonbuf), "%s%s%s", reason,
                        operreason ? "|" : "", operreason ? operreason : "");
            sendto_one(source_p, form_str(RPL_TESTLINE),
                       me.name, source_p->name,
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'k' : 'K',
                       (aconf->flags & CONF_FLAGS_TEMPORARY) ?
                       (long) ((aconf->hold - rb_current_time()) / 60) : 0L,
                       buf, reasonbuf);
            return 0;
        }
    }

    /* they asked us to check a nick, so hunt for resvs.. */
    if(name && (resv_p = find_nick_resv(name))) {
        sendto_one(source_p, form_str(RPL_TESTLINE),
                   me.name, source_p->name,
                   resv_p->hold ? 'q' : 'Q',
                   resv_p->hold ? (long) ((resv_p->hold - rb_current_time()) / 60) : 0L,
                   resv_p->host, resv_p->passwd);

        /* this is a false positive, so make sure it isn't counted in stats q
         * --nenolod
         */
        resv_p->port--;
        return 0;
    }

    /* no matching resv, we can print the I: if it exists */
    if(aconf && aconf->status & CONF_CLIENT) {
        sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
                           aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
                           show_iline_prefix(source_p, aconf, aconf->user),
                           aconf->host, aconf->port, aconf->className);
        return 0;
    }

    /* nothing matches.. */
    sendto_one(source_p, form_str(RPL_NOTESTLINE),
               me.name, source_p->name, parv[1]);
    return 0;
}
/*
 * mr_webirc - webirc message handler
 *      parv[0] = sender prefix
 *      parv[1] = password
 *      parv[2] = fake username (we ignore this)
 *	parv[3] = fake hostname 
 *	parv[4] = fake ip
 */
static int
mr_webirc(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct ConfItem *aconf;
	const char *encr;

	if (!strchr(parv[4], '.') && !strchr(parv[4], ':'))
	{
		sendto_one(source_p, "NOTICE * :Invalid IP");
		return 0;
	}

	aconf = find_address_conf(client_p->host, client_p->sockhost, 
				IsGotId(client_p) ? client_p->username : "******",
				(struct sockaddr *) &client_p->localClient->ip,
				client_p->localClient->ip.ss_family);
	if (aconf == NULL || !(aconf->status & CONF_CLIENT))
		return 0;
	if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->name, "webirc."))
	{
		/* XXX */
		sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
		return 0;
	}
	if (EmptyString(aconf->passwd))
	{
		sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
		return 0;
	}

	if (EmptyString(parv[1]))
		encr = "";
	else if (IsConfEncrypted(aconf))
		encr = crypt(parv[1], aconf->passwd);
	else
		encr = parv[1];

	if (strcmp(encr, aconf->passwd))
	{
		sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
		return 0;
	}


	strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost));

	if(strlen(parv[3]) <= HOSTLEN)
		strlcpy(source_p->host, parv[3], sizeof(source_p->host));
	else
		strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
	
	inetpton_sock(parv[4], (struct sockaddr *)&source_p->localClient->ip);

	/* Check dlines now, k/glines will be checked on registration */
	if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip, 
			       source_p->localClient->ip.ss_family)))
	{
		if(!(aconf->status & CONF_EXEMPTDLINE))
		{
			exit_client(client_p, source_p, &me, "D-lined");
			return 0;
		}
	}

	sendto_one(source_p, "NOTICE * :CGI:IRC host/IP set to %s %s", parv[3], parv[4]);
	return 0;
}
Exemple #4
0
/*
 * mr_webirc - webirc message handler
 *      parv[1] = password
 *      parv[2] = fake username (we ignore this)
 *	parv[3] = fake hostname
 *	parv[4] = fake ip
 */
static void
mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct ConfItem *aconf;
	const char *encr;
	struct rb_sockaddr_storage addr;

	aconf = find_address_conf(client_p->host, client_p->sockhost,
				IsGotId(client_p) ? client_p->username : "******",
				IsGotId(client_p) ? client_p->username : "******",
				(struct sockaddr *) &client_p->localClient->ip,
				GET_SS_FAMILY(&client_p->localClient->ip), NULL);
	if (aconf == NULL || !(aconf->status & CONF_CLIENT))
		return;
	if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
	{
		/* XXX */
		sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
		return;
	}
	if (EmptyString(aconf->passwd))
	{
		sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
		return;
	}

	if (EmptyString(parv[1]))
		encr = "";
	else if (IsConfEncrypted(aconf))
		encr = rb_crypt(parv[1], aconf->passwd);
	else
		encr = parv[1];

	if (encr == NULL || strcmp(encr, aconf->passwd))
	{
		sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
		return;
	}

	if (rb_inet_pton_sock(parv[4], (struct sockaddr *)&addr) <= 0)
	{
		sendto_one(source_p, "NOTICE * :Invalid IP");
		return;
	}

	source_p->localClient->ip = addr;

	rb_inet_ntop_sock((struct sockaddr *)&source_p->localClient->ip, source_p->sockhost, sizeof(source_p->sockhost));

	if(strlen(parv[3]) <= HOSTLEN)
		rb_strlcpy(source_p->host, parv[3], sizeof(source_p->host));
	else
		rb_strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));

	/* Check dlines now, klines will be checked on registration */
	if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip,
			       GET_SS_FAMILY(&source_p->localClient->ip))))
	{
		if(!(aconf->status & CONF_EXEMPTDLINE))
		{
			exit_client(client_p, source_p, &me, "D-lined");
			return;
		}
	}

	sendto_one(source_p, "NOTICE * :CGI:IRC host/IP set to %s %s", parv[3], parv[4]);
}
static int
mo_testline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct ConfItem *aconf;
	struct ConfItem *resv_p;
	struct rb_sockaddr_storage ip;
	const char *name = NULL;
	const char *username = NULL;
	const char *host = NULL;
	char *mask;
	char *p;
	int host_mask;
	int type;

	mask = LOCAL_COPY(parv[1]);

	if(IsChannelName(mask))
	{
		resv_p = hash_find_resv(mask);
		if(resv_p != NULL)
		{
			sendto_one_numeric(source_p, s_RPL(RPL_TESTLINE),
				   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? 'q' : 'Q',
				   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? (time_t)((resv_p->hold -
									      rb_current_time
									      ()) / 60) : (time_t)0L,
				   resv_p->host, resv_p->passwd);
			/* this is a false positive, so make sure it isn't counted in stats q
			 * --nenolod
			 */
			resv_p->port--;
		}
		else
			sendto_one_numeric(source_p, s_RPL(RPL_NOTESTLINE), parv[1]);
		return 0;
	}

	if((p = strchr(mask, '!')))
	{
		*p++ = '\0';
		name = mask;
		mask = p;

		if(EmptyString(mask))
			return 0;
	}

	if((p = strchr(mask, '@')))
	{
		*p++ = '\0';
		username = mask;
		host = p;

		if(EmptyString(host))
			return 0;
	}
	else
		host = mask;

	/* parses as an IP, check for a dline */
	if((type = parse_netmask(host, (struct sockaddr *) &ip, &host_mask)) != HM_HOST)
	{
		aconf = find_dline((struct sockaddr *) &ip);

		if(aconf && aconf->status & CONF_DLINE)
		{
			sendto_one_numeric(source_p, s_RPL(RPL_TESTLINE),
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'd' : 'D',
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ?
				   (time_t)((aconf->hold - rb_current_time()) / 60) : (time_t)0L,
				   aconf->host, aconf->passwd);

			return 0;
		}
	}

	/* now look for a matching I/K/G */
	if((aconf = find_address_conf(host, NULL, username ? username : "******",
				      (type != HM_HOST) ? (struct sockaddr *) &ip : NULL,
				      (type != HM_HOST) ? (
#ifdef RB_IPV6
										(type ==
										 HM_IPV6) ? AF_INET6
										:
#endif
										AF_INET) : 0)))
	{
		char buf[HOSTLEN + USERLEN + 2];

		if(aconf->status & CONF_KILL)
		{
			snprintf(buf, sizeof(buf), "%s@%s", aconf->user, aconf->host);
			sendto_one_numeric(source_p, s_RPL(RPL_TESTLINE),
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'k' : 'K',
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ?
				   (time_t)((aconf->hold - rb_current_time()) / 60) : (time_t)0L,
				   buf, aconf->passwd);
			return 0;
		}
		else if(aconf->status & CONF_GLINE)
		{
			snprintf(buf, sizeof(buf), "%s@%s", aconf->user, aconf->host);
			sendto_one_numeric(source_p, s_RPL(RPL_TESTLINE),
				   'G', (time_t)((aconf->hold - rb_current_time()) / 60),
				   buf, aconf->passwd);
			return 0;
		}
	}

	/* they asked us to check a nick, so hunt for resvs.. */
	if(name && (resv_p = find_nick_resv(name)))
	{
		sendto_one_numeric(source_p, s_RPL(RPL_TESTLINE),
			   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? 'q' : 'Q',
			   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? (time_t)((resv_p->hold -
								      rb_current_time()) /
								     60) : (time_t)0L, resv_p->host,
			   resv_p->passwd);

		/* this is a false positive, so make sure it isn't counted in stats q
		 * --nenolod
		 */
		resv_p->port--;
		return 0;
	}

	/* no matching resv, we can print the I: if it exists */
	if(aconf && aconf->status & CONF_CLIENT)
	{
		sendto_one_numeric(source_p, s_RPL(RPL_STATSILINE),
				   aconf->info.name, show_iline_prefix(source_p, aconf,
								       aconf->user), aconf->host,
				   aconf->port, get_class_name(aconf));
		return 0;
	}

	/* nothing matches.. */
	sendto_one_numeric(source_p, s_RPL(RPL_NOTESTLINE), parv[1]);
	return 0;
}
Exemple #6
0
/*
 * check_klines
 * inputs	- NONE
 * output	- NONE
 * side effects - Check all connections for a pending kline against the
 * 		  client, exit the client if a kline matches.
 */
void 
check_klines(void)
{               
  struct Client *client_p;          /* current local client_p being examined */
  struct ConfItem     *aconf = (struct ConfItem *)NULL;
  char          *reason;                /* pointer to reason string */
  dlink_node    *ptr, *next_ptr;
 
  for (ptr = lclient_list.head; ptr; ptr = next_ptr)
    {
      next_ptr = ptr->next;
      client_p = ptr->data;
      
      if (IsMe(client_p))
	continue;
	
      /* if there is a returned struct ConfItem then kill it */
      if ((aconf = find_dline(&client_p->localClient->ip,
			      client_p->localClient->aftype)))
	{
	  if (aconf->status & CONF_EXEMPTDLINE)
	    continue;
	    
	  sendto_realops_flags(FLAGS_ALL, L_ALL,"DLINE active for %s",
			       get_client_name(client_p, HIDE_IP));
			       
	  if (ConfigFileEntry.kline_with_connection_closed &&
	      ConfigFileEntry.kline_with_reason)
	  {
	    reason = "Connection closed";

	    if(IsPerson(client_p))
  	      sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
  	                 me.name, client_p->name,
	 	         aconf->passwd ? aconf->passwd : "D-lined");
            else
	      sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined");
	  }
	  else
	  {
	    if(ConfigFileEntry.kline_with_connection_closed)
	      reason = "Connection closed";
	    else if(ConfigFileEntry.kline_with_reason && aconf->passwd)
	      reason = aconf->passwd;
	    else
	      reason = "D-lined";

            if(IsPerson(client_p))
	      sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
	                 me.name, client_p->name, reason);
            else
	      sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined");
	  }
	    
	  (void)exit_client(client_p, client_p, &me, reason);
	  continue; /* and go examine next fd/client_p */
	}

      if (IsPerson(client_p))
	{
	  if (ConfigFileEntry.glines &&
	      (aconf = find_gkill(client_p, client_p->username)))
	    {
	      if (IsExemptKline(client_p))
		{
		  sendto_realops_flags(FLAGS_ALL, L_ALL,
				       "GLINE over-ruled for %s, client is kline_exempt",
				       get_client_name(client_p, HIDE_IP));
		  continue;
		}
	      
	      if (IsExemptGline(client_p))
		{
		  sendto_realops_flags(FLAGS_ALL, L_ALL,
				       "GLINE over-ruled for %s, client is gline_exempt",
				       get_client_name(client_p, HIDE_IP));
		  continue;
		}
       
	      sendto_realops_flags(FLAGS_ALL, L_ALL, "GLINE active for %s",
				   get_client_name(client_p, HIDE_IP));
			    
	      if(ConfigFileEntry.kline_with_connection_closed &&
	         ConfigFileEntry.kline_with_reason)
 	      {
		  reason = "Connection closed";

		  sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
		             me.name, client_p->name,
			     aconf->passwd ? aconf->passwd : "G-lined");
	      } 
	      else 
	      {
	        if(ConfigFileEntry.kline_with_connection_closed)
		  reason = "Connection closed";
		else if(ConfigFileEntry.kline_with_reason && aconf->passwd)
		  reason = aconf->passwd;
		else
		  reason = "G-lined";

		sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
		           me.name, client_p->name, reason);
	      }
	
	      (void)exit_client(client_p, client_p, &me, reason);
	      /* and go examine next fd/client_p */    
	      continue;
	    } 
	  else if((aconf = find_kill(client_p))) 
	    {
	      /* if there is a returned struct ConfItem.. then kill it */
	      if (IsExemptKline(client_p))
		{
		  sendto_realops_flags(FLAGS_ALL, L_ALL,
				       "KLINE over-ruled for %s, client is kline_exempt",
				       get_client_name(client_p, HIDE_IP));
		  continue;
		}

	      sendto_realops_flags(FLAGS_ALL, L_ALL, "KLINE active for %s",
				   get_client_name(client_p, HIDE_IP));

              if(ConfigFileEntry.kline_with_connection_closed &&
	          ConfigFileEntry.kline_with_reason)
	      {
	        reason = "Connection closed";

		sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
		           me.name, client_p->name, 
			   aconf->passwd ? aconf->passwd : "K-lined");
              }
	      else
	      {
	        if(ConfigFileEntry.kline_with_connection_closed)
		  reason = "Connection closed";
		else if(ConfigFileEntry.kline_with_reason && aconf->passwd)
		  reason = aconf->passwd;
		else
		  reason = "K-lined";

		sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
		           me.name, client_p->name, reason);
              }
	      
	      (void)exit_client(client_p, client_p, &me, reason);
	      continue; 
	    }
	}
    }
 
  /* also check the unknowns list for new dlines */
  for (ptr = unknown_list.head; ptr; ptr = next_ptr)
  {
    next_ptr = ptr->next;
    client_p = ptr->data;

    if((aconf = find_dline(&client_p->localClient->ip,
                           client_p->localClient->aftype)))
    {
      if(aconf->status & CONF_EXEMPTDLINE)
        continue;

      sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined");
      exit_client(client_p, client_p, &me, "D-lined");
    }
  }

}