/* This code is in the public domain.
- * $Id: newconf.c 3550 2007-08-09 06:47:26Z nenolod $
*/
#include "stdinc.h"
#include "newconf.h"
#include "ircd_defs.h"
-#include "common.h"
#include "logger.h"
#include "s_conf.h"
#include "s_user.h"
#include "cache.h"
#include "ircd.h"
#include "snomask.h"
-#include "blacklist.h"
#include "sslproc.h"
#include "privilege.h"
#include "chmode.h"
static char *yy_blacklist_host = NULL;
static char *yy_blacklist_reason = NULL;
-static int yy_blacklist_ipv4 = 1;
-static int yy_blacklist_ipv6 = 0;
-static rb_dlink_list yy_blacklist_filters;
+static uint8_t yy_blacklist_iptype = 0;
+static rb_dlink_list yy_blacklist_filters = { NULL, NULL, 0 };
+
+static char *yy_opm_address_ipv4 = NULL;
+static char *yy_opm_address_ipv6 = NULL;
+static uint16_t yy_opm_port_ipv4 = 0;
+static uint16_t yy_opm_port_ipv6 = 0;
static char *yy_privset_extends = NULL;
{
if(rb_inet_pton(AF_INET, (char *) data, &ServerInfo.ip.sin_addr) <= 0)
{
- conf_report_error("Invalid netmask for server IPv4 vhost (%s)", (char *) data);
+ conf_report_error("Invalid IPv4 address for server vhost (%s)", (char *) data);
return;
}
ServerInfo.ip.sin_family = AF_INET;
#ifdef RB_IPV6
if(rb_inet_pton(AF_INET6, (char *) data, &ServerInfo.ip6.sin6_addr) <= 0)
{
- conf_report_error("Invalid netmask for server IPv6 vhost (%s)", (char *) data);
+ conf_report_error("Invalid IPv6 address for server vhost (%s)", (char *) data);
return;
}
m_bn = rb_basename((char *) data);
if(findmodule_byname(m_bn) == -1)
- load_one_module((char *) data, 0);
+ load_one_module((char *) data, MAPI_ORIGIN_EXTENSION, 0);
rb_free(m_bn);
}
{ "rehash", SHARED_REHASH },
{ "grant", SHARED_GRANT },
{ "die", SHARED_DIE },
+ { "module", SHARED_MODULE },
{ "all", SHARED_ALL },
{ "none", 0 },
{NULL, 0}
}
if(listener_address == NULL)
{
+ if (!ssl)
+ {
+ conf_report_warning("listener 'ANY/%d': support for plaintext listeners may be removed in a future release per RFC 7194. "
+ "It is suggested that users be migrated to SSL/TLS connections.", args->v.number);
+ }
add_listener(args->v.number, listener_address, AF_INET, ssl, ssl || yy_defer_accept);
#ifdef RB_IPV6
add_listener(args->v.number, listener_address, AF_INET6, ssl, ssl || yy_defer_accept);
#endif
family = AF_INET;
- add_listener(args->v.number, listener_address, family, ssl, ssl || yy_defer_accept);
+ if (!ssl)
+ {
+ conf_report_warning("listener '%s/%d': support for plaintext listeners may be removed in a future release per RFC 7194. "
+ "It is suggested that users be migrated to SSL/TLS connections.", listener_address, args->v.number);
+ }
+ add_listener(args->v.number, listener_address, family, ssl, ssl || yy_defer_accept);
}
}
{
if(rb_inet_pton_sock(data, (struct sockaddr *)&yy_server->my_ipnum) <= 0)
{
- conf_report_error("Invalid netmask for server vhost (%s)",
+ conf_report_error("Invalid IP address for server connect vhost (%s)",
(char *) data);
return;
}
ConfigFileEntry.kline_delay = *(unsigned int *) data;
/* THIS MUST BE HERE to stop us being unable to check klines */
- kline_queued = 0;
+ kline_queued = false;
}
static void
return -1;
}
- irc_dictionary_add(alias_dict, yy_alias->name, yy_alias);
+ rb_dictionary_add(alias_dict, yy_alias->name, yy_alias);
return 0;
}
/* XXX for below */
static void conf_set_blacklist_reason(void *data);
+#define IPTYPE_IPV4 1
+#define IPTYPE_IPV6 2
+
static void
conf_set_blacklist_host(void *data)
{
return;
}
- yy_blacklist_ipv4 = 1;
- yy_blacklist_ipv6 = 0;
+ yy_blacklist_iptype |= IPTYPE_IPV4;
yy_blacklist_host = rb_strdup(data);
}
conf_parm_t *args = data;
/* Don't assume we have either if we got here */
- yy_blacklist_ipv4 = 0;
- yy_blacklist_ipv6 = 0;
+ yy_blacklist_iptype = 0;
for (; args; args = args->next)
{
if (!strcasecmp(args->v.string, "ipv4"))
- yy_blacklist_ipv4 = 1;
+ yy_blacklist_iptype |= IPTYPE_IPV4;
else if (!strcasecmp(args->v.string, "ipv6"))
- yy_blacklist_ipv6 = 1;
+ yy_blacklist_iptype |= IPTYPE_IPV6;
else
conf_report_error("blacklist::type has unknown address family %s",
args->v.string);
}
/* If we have neither, just default to IPv4 */
- if (!yy_blacklist_ipv4 && !yy_blacklist_ipv6)
+ if (!yy_blacklist_iptype)
{
- conf_report_error("blacklist::type has neither IPv4 nor IPv6 (defaulting to IPv4)");
- yy_blacklist_ipv4 = 1;
+ conf_report_warning("blacklist::type has neither IPv4 nor IPv6 (defaulting to IPv4)");
+ yy_blacklist_iptype = IPTYPE_IPV4;
}
}
conf_set_blacklist_matches(void *data)
{
conf_parm_t *args = data;
+ enum filter_t { FILTER_NONE, FILTER_ALL, FILTER_LAST };
for (; args; args = args->next)
{
- struct BlacklistFilter *filter;
char *str = args->v.string;
char *p;
- int type = BLACKLIST_FILTER_LAST;
+ enum filter_t type = FILTER_LAST;
if (CF_TYPE(args->type) != CF_QSTRING)
{
{
/* Check for validity */
if (*p == '.')
- type = BLACKLIST_FILTER_ALL;
- else if (!isalnum((unsigned char)*p))
+ type = FILTER_ALL;
+ else if (!isdigit((unsigned char)*p))
{
conf_report_error("blacklist::matches has invalid IP match entry %s",
str);
- type = 0;
+ type = FILTER_NONE;
break;
}
}
- if (type == BLACKLIST_FILTER_ALL)
+ if (type == FILTER_ALL)
{
/* Basic IP sanity check */
struct rb_sockaddr_storage tmp;
continue;
}
}
- else if (type == BLACKLIST_FILTER_LAST)
+ else if (type == FILTER_LAST)
{
/* Verify it's the correct length */
if (strlen(str) > 3)
continue; /* Invalid entry */
}
- filter = rb_malloc(sizeof(struct BlacklistFilter));
- filter->type = type;
- rb_strlcpy(filter->filterstr, str, sizeof(filter->filterstr));
-
- rb_dlinkAdd(filter, &filter->node, &yy_blacklist_filters);
+ rb_dlinkAddAlloc(rb_strdup(str), &yy_blacklist_filters);
}
}
if (yy_blacklist_host && data)
{
yy_blacklist_reason = rb_strdup(data);
- if (yy_blacklist_ipv6)
+ if (yy_blacklist_iptype & IPTYPE_IPV6)
{
- /* Make sure things fit (64 = alnum count + dots) */
+ /* Make sure things fit (magic number 64 = alnum count + dots)
+ * Example: 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa
+ */
if ((64 + strlen(yy_blacklist_host)) > IRCD_RES_HOSTLEN)
{
conf_report_error("blacklist::host %s results in IPv6 queries that are too long",
}
}
/* Avoid doing redundant check, IPv6 is bigger than IPv4 --Elizabeth */
- if (yy_blacklist_ipv4 && !yy_blacklist_ipv6)
+ if ((yy_blacklist_iptype & IPTYPE_IPV4) && !(yy_blacklist_iptype & IPTYPE_IPV6))
{
- /* Make sure things fit (16 = number of nums + dots) */
+ /* Make sure things fit for worst case (magic number 16 = number of nums + dots)
+ * Example: 127.127.127.127.in-addr.arpa
+ */
if ((16 + strlen(yy_blacklist_host)) > IRCD_RES_HOSTLEN)
{
conf_report_error("blacklist::host %s results in IPv4 queries that are too long",
}
}
- new_blacklist(yy_blacklist_host, yy_blacklist_reason, yy_blacklist_ipv4, yy_blacklist_ipv6,
- &yy_blacklist_filters);
+ add_blacklist(yy_blacklist_host, yy_blacklist_reason, yy_blacklist_iptype, &yy_blacklist_filters);
}
cleanup_bl:
- if (data == NULL)
- {
- RB_DLINK_FOREACH_SAFE(ptr, nptr, yy_blacklist_filters.head)
- {
- rb_dlinkDelete(ptr, &yy_blacklist_filters);
- rb_free(ptr);
- }
- }
- else
+ RB_DLINK_FOREACH_SAFE(ptr, nptr, yy_blacklist_filters.head)
{
- yy_blacklist_filters = (rb_dlink_list){ NULL, NULL, 0 };
+ rb_free(ptr->data);
+ rb_dlinkDestroy(ptr, &yy_blacklist_filters);
}
+ yy_blacklist_filters = (rb_dlink_list){ NULL, NULL, 0 };
+
rb_free(yy_blacklist_host);
rb_free(yy_blacklist_reason);
yy_blacklist_host = NULL;
yy_blacklist_reason = NULL;
- yy_blacklist_ipv4 = 1;
- yy_blacklist_ipv6 = 0;
+ yy_blacklist_iptype = 0;
+}
+
+static int
+conf_begin_opm(struct TopConf *tc)
+{
+ yy_opm_address_ipv4 = yy_opm_address_ipv6 = NULL;
+ yy_opm_port_ipv4 = yy_opm_port_ipv6 = 0;
+ return 0;
+}
+
+static int
+conf_end_opm(struct TopConf *tc)
+{
+ if(yy_opm_port_ipv4 > 0)
+ {
+ if(yy_opm_address_ipv4 != NULL)
+ create_opm_listener(yy_opm_address_ipv4, yy_opm_port_ipv4);
+ else
+ {
+ char ip[HOSTIPLEN];
+ if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.ip, ip, sizeof(ip)))
+ {
+ conf_report_error("No opm::listen_ipv4 nor serverinfo::vhost directive; cannot listen on IPv4");
+ return 1;
+ }
+ else
+ {
+ create_opm_listener(ip, yy_opm_port_ipv4);
+ }
+ }
+ }
+
+ if(yy_opm_port_ipv6 > 0)
+ {
+ if(yy_opm_address_ipv6 != NULL)
+ create_opm_listener(yy_opm_address_ipv6, yy_opm_port_ipv6);
+ else
+ {
+ char ip[HOSTIPLEN];
+ if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.ip6, ip, sizeof(ip)))
+ {
+ conf_report_error("No opm::listen_ipv6 nor serverinfo::vhost directive; cannot listen on IPv6");
+ return 1;
+ }
+ else
+ {
+ create_opm_listener(ip, yy_opm_port_ipv6);
+ }
+ }
+ }
+
+ rb_free(yy_opm_address_ipv4);
+ rb_free(yy_opm_address_ipv6);
+ return 0;
+}
+
+static void
+conf_set_opm_listen_address_ipv4(void *data)
+{
+ struct rb_sockaddr_storage addr;
+ char *ip = data;
+
+ if(ip == NULL)
+ {
+ conf_report_error("opm::listen_ipv4 cannot be empty");
+ return;
+ }
+
+ /* Test the address for validity */
+ if(!rb_inet_pton_sock(ip, (struct sockaddr *)&addr))
+ {
+ conf_report_error("opm::listen_ipv4 is invalid: %s", ip);
+ return;
+ }
+
+#ifdef RB_IPV6
+ if(GET_SS_FAMILY(&addr) == AF_INET6)
+ {
+ conf_report_error("opm::listen_ipv4 is an IPv6 address: %s", ip);
+ return;
+ }
+#endif
+
+ if(yy_opm_address_ipv4 != NULL)
+ {
+ conf_report_error("opm::listen_ipv4 %s overwrites previous one: %s",
+ ip, yy_opm_address_ipv4);
+ return;
+ }
+
+ yy_opm_address_ipv4 = rb_strdup(ip);
+}
+
+static void
+conf_set_opm_listen_address_ipv6(void *data)
+{
+#ifndef RB_IPV6
+ conf_report_error("opm::listen_ipv6 requires IPv6 support in your ircd");
+ return;
+#else
+ struct rb_sockaddr_storage addr;
+ char *ip = data;
+
+ if(ip == NULL)
+ {
+ conf_report_error("opm::listen_ipv4 cannot be empty");
+ return;
+ }
+
+ /* Test the address for validity */
+ if(!rb_inet_pton_sock(ip, (struct sockaddr *)&addr))
+ {
+ conf_report_error("opm::listen_ipv6 is invalid: %s", ip);
+ return;
+ }
+
+ if(GET_SS_FAMILY(&addr) == AF_INET)
+ {
+ conf_report_error("opm::listen_ipv6 is an IPv4 address: %s", ip);
+ return;
+ }
+
+ if(yy_opm_address_ipv6 != NULL)
+ {
+ conf_report_error("opm::listen_ipv6 %s overwrites previous one: %s",
+ ip, yy_opm_address_ipv6);
+ return;
+ }
+
+ yy_opm_address_ipv6 = rb_strdup(ip);
+#endif
+}
+
+static void
+conf_set_opm_listen_port_ipv4(void *data)
+{
+#ifndef RB_IPV6
+ conf_report_error("opm::listen_ipv6 requires IPv6 support in your ircd");
+ return;
+#else
+ int port = *((int *)data);
+
+ if(port > 65535 || port <= 0)
+ {
+ conf_report_error("opm::port_ipv4 is out of range: %d", port);
+ return;
+ }
+
+ if(yy_opm_port_ipv4)
+ {
+ conf_report_error("opm::port_ipv4 %d overwrites existing port %hu",
+ port, yy_opm_port_ipv4);
+ return;
+ }
+
+ yy_opm_port_ipv4 = (uint16_t)port;
+#endif
+}
+
+static void
+conf_set_opm_listen_port_ipv6(void *data)
+{
+ int port = *((int *)data);
+
+ if(port > 65535 || port <= 0)
+ {
+ conf_report_error("opm::port_ipv6 is out of range: %d", port);
+ return;
+ }
+
+ if(yy_opm_port_ipv6)
+ {
+ conf_report_error("opm::port_ipv6 %d overwrites existing port %hu",
+ port, yy_opm_port_ipv6);
+ return;
+ }
+
+ yy_opm_port_ipv6 = (uint16_t)port;
+}
+
+static void
+conf_set_opm_listen_port(void *data)
+{
+ int port = *((int *)data);
+ bool fail = false; /* Allow us to report shadowing of IPv4 and IPv6 port */
+
+ if(port > 65535 || port <= 0)
+ {
+ conf_report_error("opm::port is out of range: %d", port);
+ return;
+ }
+
+ if(yy_opm_port_ipv4)
+ {
+ conf_report_error("opm::port %d overwrites existing IPv4 port %hu",
+ port, yy_opm_port_ipv4);
+ fail = true;
+ }
+
+ if(yy_opm_port_ipv6)
+ {
+ conf_report_error("opm::port %d overwrites existing IPv6 port %hu",
+ port, yy_opm_port_ipv6);
+ fail = true;
+ }
+
+ if(fail)
+ return;
+
+ yy_opm_port_ipv4 = yy_opm_port_ipv6 = (uint16_t)port;
}
/* public functions */
conf_report_error(const char *fmt, ...)
{
va_list ap;
- char msg[IRCD_BUFSIZE + 1] = { 0 };
+ char msg[BUFSIZE + 1] = { 0 };
va_start(ap, fmt);
- rb_vsnprintf(msg, IRCD_BUFSIZE, fmt, ap);
+ vsnprintf(msg, BUFSIZE, fmt, ap);
va_end(ap);
if (testing_conf)
}
ierror("\"%s\", line %d: %s", current_file, lineno + 1, msg);
- sendto_realops_snomask(SNO_GENERAL, L_ALL, "\"%s\", line %d: %s", current_file, lineno + 1, msg);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "error: \"%s\", line %d: %s", current_file, lineno + 1, msg);
+}
+
+void
+conf_report_warning(const char *fmt, ...)
+{
+ va_list ap;
+ char msg[BUFSIZE + 1] = { 0 };
+
+ va_start(ap, fmt);
+ vsnprintf(msg, BUFSIZE, fmt, ap);
+ va_end(ap);
+
+ if (testing_conf)
+ {
+ fprintf(stderr, "\"%s\", line %d: %s\n", current_file, lineno + 1, msg);
+ return;
+ }
+
+ iwarn("\"%s\", line %d: %s", current_file, lineno + 1, msg);
+ sendto_realops_snomask(SNO_GENERAL, L_ALL, "warning: \"%s\", line %d: %s", current_file, lineno + 1, msg);
}
int
static struct ConfEntry conf_serverinfo_table[] =
{
{ "description", CF_QSTRING, NULL, 0, &ServerInfo.description },
- { "hub", CF_YESNO, NULL, 0, &ServerInfo.hub },
{ "network_name", CF_QSTRING, conf_set_serverinfo_network_name, 0, NULL },
{ "name", CF_QSTRING, conf_set_serverinfo_name, 0, NULL },
{ "client_flood_message_time", CF_INT, NULL, 0, &ConfigFileEntry.client_flood_message_time },
{ "max_ratelimit_tokens", CF_INT, NULL, 0, &ConfigFileEntry.max_ratelimit_tokens },
{ "away_interval", CF_INT, NULL, 0, &ConfigFileEntry.away_interval },
+ { "hide_opers_in_whois", CF_YESNO, NULL, 0, &ConfigFileEntry.hide_opers_in_whois },
{ "certfp_method", CF_STRING, conf_set_general_certfp_method, 0, NULL },
{ "\0", 0, NULL, 0, NULL }
};
{ "disable_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.disable_local_channels },
{ "autochanmodes", CF_QSTRING, conf_set_channel_autochanmodes, 0, NULL },
{ "displayed_usercount", CF_INT, NULL, 0, &ConfigChannel.displayed_usercount },
+ { "strip_topic_colors", CF_YESNO, NULL, 0, &ConfigChannel.strip_topic_colors },
{ "\0", 0, NULL, 0, NULL }
};
add_conf_item("blacklist", "type", CF_STRING | CF_FLIST, conf_set_blacklist_type);
add_conf_item("blacklist", "matches", CF_QSTRING | CF_FLIST, conf_set_blacklist_matches);
add_conf_item("blacklist", "reject_reason", CF_QSTRING, conf_set_blacklist_reason);
+
+ add_top_conf("opm", conf_begin_opm, conf_end_opm, NULL);
+ add_conf_item("opm", "listen_ipv4", CF_QSTRING, conf_set_opm_listen_address_ipv4);
+ add_conf_item("opm", "port_v4", CF_INT, conf_set_opm_listen_port_ipv4);
+ add_conf_item("opm", "listen_ipv6", CF_QSTRING, conf_set_opm_listen_address_ipv6);
+ add_conf_item("opm", "port_v6", CF_INT, conf_set_opm_listen_port_ipv6);
+ add_conf_item("opm", "listen_port", CF_INT, conf_set_opm_listen_port);
}