コード例 #1
0
ファイル: m_starttls.c プロジェクト: maxteufel/charybdis
static int
mr_starttls(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
#ifdef HAVE_LIBCRYPTO
	ssl_ctl_t *ctl;
	rb_fde_t *F[2];

	if (!MyConnect(client_p))
		return 0;

	if (IsSSL(client_p))
	{
		sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "Nested TLS handshake not allowed");
		return 1;
	}

	if (!ssl_ok || !get_ssld_count())
	{
		sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "TLS is not configured");
		return 1;
	}

	if (rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &F[0], &F[1], "STARTTLS ssld session") == -1)
	{
		ilog_error("error creating SSL/TLS socketpair for ssld slave");
		sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "Unable to create SSL/TLS socketpair for ssld offload slave");
		return 1;
	}

	s_assert(client_p->localClient != NULL);

	/* clear out any remaining plaintext lines */
	rb_linebuf_donebuf(&client_p->localClient->buf_recvq);

	sendto_one_numeric(client_p, RPL_STARTTLS, form_str(RPL_STARTTLS));
	send_queued(client_p);

	ctl = start_ssld_accept(client_p->localClient->F, F[1], rb_get_fd(F[0]));
	if (ctl != NULL)
	{
		client_p->localClient->F = F[0];
		client_p->localClient->ssl_ctl = ctl;
		SetSSL(client_p);
	}
	else
		return 1;

#else
	sendto_one_numeric(client_p, ERR_STARTTLS, form_str(ERR_STARTTLS), "TLS is not configured");
#endif
	return 0;
}
コード例 #2
0
ファイル: m_connect.c プロジェクト: maxteufel/charybdis
/*
 * mo_connect - CONNECT command handler
 *
 * Added by Jto 11 Feb 1989
 *
 * m_connect
 *      parv[1] = servername
 *      parv[2] = port number
 *      parv[3] = remote server
 */
static int
mo_connect(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	int port;
	int tmpport;
	struct server_conf *server_p;
	struct Client *target_p;

	/* always privileged with handlers */

	if(MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
	{
		sendto_one(source_p, form_str(ERR_NOPRIVS),
			   me.name, source_p->name, "remote");
		return 0;
	}

	if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
		return 0;

	if((target_p = find_server(source_p, parv[1])))
	{
		sendto_one_notice(source_p, ":Connect: Server %s already exists from %s.", parv[1],
			target_p->from->name);
		return 0;
	}

	/*
	 * try to find the name, then host, if both fail notify ops and bail
	 */
	if((server_p = find_server_conf(parv[1])) == NULL)
	{
		sendto_one_notice(source_p, ":Connect: Host %s not listed in ircd.conf", parv[1]);
		return 0;
	}

	if(ServerConfSSL(server_p) && (!ssl_ok || !get_ssld_count()))
	{
		sendto_one_notice(source_p,
				  ":Connect: Server %s is set to use SSL/TLS but SSL/TLS is not configured.",
				  parv[1]);
		return 0;
	}

	/*
	 * Get port number from user, if given. If not specified,
	 * use the default form configuration structure. If missing
	 * from there, then use the precompiled default.
	 */
	tmpport = port = 0;
	if(parc > 2 && !EmptyString(parv[2]))
		port = atoi(parv[2]);
	if(port == 0 && server_p->port)
		port = server_p->port;
	else if(port <= 0)
	{
		sendto_one_notice(source_p, ":Connect: illegal port number");
		return 0;
	}
	
	/*
	 * Notify all operators about remote connect requests
	 */

	ilog(L_SERVER, "CONNECT From %s : %s %s", source_p->name, parv[1], parc > 2 ? parv[2] : "");

	server_p->port = port;
	/*
	 * at this point we should be calling connect_server with a valid
	 * C:line and a valid port in the C:line
	 */
	if(serv_connect(server_p, source_p))
	{
			sendto_one_notice(source_p, ":*** Connecting to %s.%d",
				server_p->name, server_p->port);
	}
	else
	{
		sendto_one_notice(source_p, ":*** Couldn't connect to %s.%d",
			server_p->name, server_p->port);
	}

	/*
	 * client is either connecting with all the data it needs or has been
	 * destroyed
	 */
	server_p->port = tmpport;
	return 0;
}
コード例 #3
0
ファイル: listener.c プロジェクト: Macs/NeoIRCd
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);
		/* Re-register a new IO request for the next accept .. */
		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;
}
コード例 #4
0
ファイル: m_connect.c プロジェクト: maxteufel/charybdis
/*
 * ms_connect - CONNECT command handler
 *
 * Added by Jto 11 Feb 1989
 *
 * m_connect
 *      parv[1] = servername
 *      parv[2] = port number
 *      parv[3] = remote server
 */
static int
ms_connect(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	int port;
	int tmpport;
	struct server_conf *server_p;
	struct Client *target_p;

	if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
		return 0;

	if((target_p = find_server(NULL, parv[1])))
	{
		sendto_one_notice(source_p, ":Connect: Server %s already exists from %s.",
				  parv[1], target_p->from->name);
		return 0;
	}

	/*
	 * try to find the name, then host, if both fail notify ops and bail
	 */
	if((server_p = find_server_conf(parv[1])) == NULL)
	{
		sendto_one_notice(source_p, ":Connect: Host %s not listed in ircd.conf",
				  parv[1]);
		return 0;
	}

	if(ServerConfSSL(server_p) && (!ssl_ok || !get_ssld_count()))
	{
		sendto_one_notice(source_p,
				  ":Connect: Server %s is set to use SSL/TLS but SSL/TLS is not configured.",
				  parv[1]);
		return 0;
	}

	/*
	 * Get port number from user, if given. If not specified,
	 * use the default form configuration structure. If missing
	 * from there, then use the precompiled default.
	 */
	tmpport = server_p->port;

	port = atoi(parv[2]);

	/* if someone sends port 0, and we have a config port.. use it */
	if(port == 0 && server_p->port)
		port = server_p->port;
	else if(port <= 0)
	{
		sendto_one_notice(source_p, ":Connect: Illegal port number");
		return 0;
	}

	/*
	 * Notify all operators about remote connect requests
	 */
	sendto_wallops_flags(UMODE_WALLOP, &me,
			     "Remote CONNECT %s %d from %s",
			     parv[1], port, source_p->name);
	sendto_server(NULL, NULL, CAP_TS6, NOCAPS,
		      ":%s WALLOPS :Remote CONNECT %s %d from %s",
		      me.id, parv[1], port, source_p->name);

	ilog(L_SERVER, "CONNECT From %s : %s %d", source_p->name, parv[1], port);

	server_p->port = port;
	/*
	 * at this point we should be calling connect_server with a valid
	 * C:line and a valid port in the C:line
	 */
	if(serv_connect(server_p, source_p))
		sendto_one_notice(source_p, ":*** Connecting to %s.%d",
				  server_p->name, server_p->port);
	else
		sendto_one_notice(source_p, ":*** Couldn't connect to %s.%d",
				  server_p->name, server_p->port);
	/*
	 * client is either connecting with all the data it needs or has been
	 * destroyed
	 */
	server_p->port = tmpport;
	return 0;
}