#include "wsproc.h"
#include "privilege.h"
#include "chmode.h"
+#include "certfp.h"
#define CF_TYPE(x) ((x) & CF_MTYPE)
RB_DLINK_FOREACH(d, conf_items.head)
{
tc = d->data;
- if(strcasecmp(tc->tc_name, name) == 0)
+ if(rb_strcasecmp(tc->tc_name, name) == 0)
return tc;
}
{
cf = &top->tc_entries[i];
- if(!strcasecmp(cf->cf_name, name))
+ if(!rb_strcasecmp(cf->cf_name, name))
return cf;
}
}
RB_DLINK_FOREACH(d, top->tc_items.head)
{
cf = d->data;
- if(strcasecmp(cf->cf_name, name) == 0)
+ if(rb_strcasecmp(cf->cf_name, name) == 0)
return cf;
}
return;
}
- strcpy(ServerInfo.sid, sid);
+ rb_strlcpy(ServerInfo.sid, sid, sizeof(ServerInfo.sid));
}
}
static void
conf_set_serverinfo_vhost(void *data)
{
- if(rb_inet_pton(AF_INET, (char *) data, &ServerInfo.ip.sin_addr) <= 0)
+ struct rb_sockaddr_storage addr;
+
+ if(rb_inet_pton_sock(data, &addr) <= 0 || GET_SS_FAMILY(&addr) != AF_INET)
{
conf_report_error("Invalid IPv4 address for server vhost (%s)", (char *) data);
return;
}
- ServerInfo.ip.sin_family = AF_INET;
- ServerInfo.specific_ipv4_vhost = 1;
+
+ ServerInfo.bind4 = addr;
}
static void
conf_set_serverinfo_vhost6(void *data)
{
-#ifdef RB_IPV6
- if(rb_inet_pton(AF_INET6, (char *) data, &ServerInfo.ip6.sin6_addr) <= 0)
+
+ struct rb_sockaddr_storage addr;
+
+ if(rb_inet_pton_sock(data, &addr) <= 0 || GET_SS_FAMILY(&addr) != AF_INET6)
{
conf_report_error("Invalid IPv6 address for server vhost (%s)", (char *) data);
return;
}
- ServerInfo.specific_ipv6_vhost = 1;
- ServerInfo.ip6.sin6_family = AF_INET6;
-#else
- conf_report_error("Warning -- ignoring serverinfo::vhost6 -- IPv6 support not available.");
-#endif
+ ServerInfo.bind6 = addr;
}
static void
m_bn = rb_basename((char *) data);
- if(findmodule_byname(m_bn) == -1)
- load_one_module((char *) data, MAPI_ORIGIN_EXTENSION, 0);
+ if(findmodule_byname(m_bn) == NULL)
+ load_one_module((char *) data, MAPI_ORIGIN_EXTENSION, false);
rb_free(m_bn);
}
{"need_ssl", CONF_FLAGS_NEED_SSL },
{"need_sasl", CONF_FLAGS_NEED_SASL },
{"extend_chans", CONF_FLAGS_EXTEND_CHANS },
+ {"allow_sctp", CONF_FLAGS_ALLOW_SCTP },
{NULL, 0}
};
{ "compressed", SERVER_COMPRESSED },
{ "encrypted", SERVER_ENCRYPTED },
{ "topicburst", SERVER_TB },
+ { "sctp", SERVER_SCTP },
{ "ssl", SERVER_SSL },
+ { "no-export", SERVER_NO_EXPORT },
{ NULL, 0 },
};
}
-#ifdef RB_IPV6
static void
conf_set_class_cidr_ipv6_bitlen(void *data)
{
yy_class->cidr_ipv6_bitlen = *(unsigned int *) data;
}
-#endif
static void
conf_set_class_number_per_cidr(void *data)
yy_class->max_sendq = *(unsigned int *) data;
}
-static char *listener_address;
+static char *listener_address[2];
static int
conf_begin_listen(struct TopConf *tc)
{
- rb_free(listener_address);
- listener_address = NULL;
+ for (int i = 0; i < ARRAY_SIZE(listener_address); i++) {
+ rb_free(listener_address[i]);
+ listener_address[i] = NULL;
+ }
+ yy_wsock = 0;
+ yy_defer_accept = 0;
return 0;
}
static int
conf_end_listen(struct TopConf *tc)
{
- rb_free(listener_address);
- listener_address = NULL;
+ for (int i = 0; i < ARRAY_SIZE(listener_address); i++) {
+ rb_free(listener_address[i]);
+ listener_address[i] = NULL;
+ }
+ yy_wsock = 0;
+ yy_defer_accept = 0;
return 0;
}
}
static void
-conf_set_listen_port_both(void *data, int ssl)
+conf_set_listen_port_both(void *data, int ssl, int sctp)
{
conf_parm_t *args = data;
for (; args; args = args->next)
{
if(CF_TYPE(args->type) != CF_INT)
{
- conf_report_error
- ("listener::port argument is not an integer " "-- ignoring.");
+ conf_report_error("listener::port argument is not an integer -- ignoring.");
continue;
}
- if(listener_address == NULL)
+ if(listener_address[0] == 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);
+ if (sctp) {
+ conf_report_error("listener::sctp_port has no addresses -- ignoring.");
+ } else {
+ add_tcp_listener(args->v.number, NULL, AF_INET, ssl, ssl || yy_defer_accept, yy_wsock);
+ add_tcp_listener(args->v.number, NULL, AF_INET6, ssl, ssl || yy_defer_accept, yy_wsock);
}
- add_listener(args->v.number, listener_address, AF_INET, ssl, ssl || yy_defer_accept, yy_wsock);
-#ifdef RB_IPV6
- add_listener(args->v.number, listener_address, AF_INET6, ssl, ssl || yy_defer_accept, yy_wsock);
-#endif
}
else
{
int family;
-#ifdef RB_IPV6
- if(strchr(listener_address, ':') != NULL)
+ if(strchr(listener_address[0], ':') != NULL)
family = AF_INET6;
else
-#endif
family = AF_INET;
- 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);
+ if (sctp) {
+#ifdef HAVE_LIBSCTP
+ add_sctp_listener(args->v.number, listener_address[0], listener_address[1], ssl, yy_wsock);
+#else
+ conf_report_error("Warning -- ignoring listener::sctp_port -- SCTP support not available.");
+#endif
+ } else {
+ add_tcp_listener(args->v.number, listener_address[0], family, ssl, ssl || yy_defer_accept, yy_wsock);
}
-
- add_listener(args->v.number, listener_address, family, ssl, ssl || yy_defer_accept, yy_wsock);
}
}
}
static void
conf_set_listen_port(void *data)
{
- conf_set_listen_port_both(data, 0);
+ conf_set_listen_port_both(data, 0, 0);
}
static void
conf_set_listen_sslport(void *data)
{
- conf_set_listen_port_both(data, 1);
+ conf_set_listen_port_both(data, 1, 0 );
+}
+
+static void
+conf_set_listen_sctp_port(void *data)
+{
+ conf_set_listen_port_both(data, 0, 1);
+}
+
+static void
+conf_set_listen_sctp_sslport(void *data)
+{
+ conf_set_listen_port_both(data, 1, 1);
}
static void
conf_set_listen_address(void *data)
{
- rb_free(listener_address);
- listener_address = rb_strdup(data);
+ rb_free(listener_address[1]);
+ listener_address[1] = listener_address[0];
+ listener_address[0] = rb_strdup(data);
}
static int
return 0;
}
- if(EmptyString(yy_server->host))
+ if((yy_server->flags & SERVER_SSL) && EmptyString(yy_server->certfp))
+ {
+ conf_report_error("Ignoring connect block for %s -- no fingerprint provided for SSL connection.",
+ yy_server->name);
+ return 0;
+ }
+
+ if(EmptyString(yy_server->connect_host)
+ && GET_SS_FAMILY(&yy_server->connect4) != AF_INET
+ && GET_SS_FAMILY(&yy_server->connect6) != AF_INET6
+ )
{
conf_report_error("Ignoring connect block for %s -- missing host.",
yy_server->name);
static void
conf_set_connect_host(void *data)
{
- rb_free(yy_server->host);
- yy_server->host = rb_strdup(data);
- if (strchr(yy_server->host, ':'))
- yy_server->aftype = AF_INET6;
+ struct rb_sockaddr_storage addr;
+
+ if(rb_inet_pton_sock(data, &addr) <= 0)
+ {
+ rb_free(yy_server->connect_host);
+ yy_server->connect_host = rb_strdup(data);
+ }
+ else if(GET_SS_FAMILY(&addr) == AF_INET)
+ {
+ yy_server->connect4 = addr;
+ }
+ else if(GET_SS_FAMILY(&addr) == AF_INET6)
+ {
+ yy_server->connect6 = addr;
+ }
+ else
+ {
+ conf_report_error("Unsupported IP address for server connect host (%s)",
+ (char *)data);
+ return;
+ }
}
static void
conf_set_connect_vhost(void *data)
{
- if(rb_inet_pton_sock(data, (struct sockaddr *)&yy_server->my_ipnum) <= 0)
+ struct rb_sockaddr_storage addr;
+
+ if(rb_inet_pton_sock(data, &addr) <= 0)
+ {
+ rb_free(yy_server->bind_host);
+ yy_server->bind_host = rb_strdup(data);
+ }
+ else if(GET_SS_FAMILY(&addr) == AF_INET)
+ {
+ yy_server->bind4 = addr;
+ }
+ else if(GET_SS_FAMILY(&addr) == AF_INET6)
+ {
+ yy_server->bind6 = addr;
+ }
+ else
{
- conf_report_error("Invalid IP address for server connect vhost (%s)",
- (char *) data);
+ conf_report_error("Unsupported IP address for server connect vhost (%s)",
+ (char *)data);
return;
}
-
- yy_server->flags |= SERVER_VHOSTED;
}
static void
{
char *aft = data;
- if(strcasecmp(aft, "ipv4") == 0)
+ if(rb_strcasecmp(aft, "ipv4") == 0)
yy_server->aftype = AF_INET;
-#ifdef RB_IPV6
- else if(strcasecmp(aft, "ipv6") == 0)
+ else if(rb_strcasecmp(aft, "ipv6") == 0)
yy_server->aftype = AF_INET6;
-#endif
else
conf_report_error("connect::aftype '%s' is unknown.", aft);
}
{
char *val = data;
- if(strcasecmp(val, "yes") == 0)
+ if(rb_strcasecmp(val, "yes") == 0)
ConfigFileEntry.hide_error_messages = 2;
- else if(strcasecmp(val, "opers") == 0)
+ else if(rb_strcasecmp(val, "opers") == 0)
ConfigFileEntry.hide_error_messages = 1;
- else if(strcasecmp(val, "no") == 0)
+ else if(rb_strcasecmp(val, "no") == 0)
ConfigFileEntry.hide_error_messages = 0;
else
conf_report_error("Invalid setting '%s' for general::hide_error_messages.", val);
}
-static void
-conf_set_general_kline_delay(void *data)
-{
- ConfigFileEntry.kline_delay = *(unsigned int *) data;
-
- /* THIS MUST BE HERE to stop us being unable to check klines */
- kline_queued = false;
-}
-
static void
conf_set_general_stats_k_oper_only(void *data)
{
char *val = data;
- if(strcasecmp(val, "yes") == 0)
+ if(rb_strcasecmp(val, "yes") == 0)
ConfigFileEntry.stats_k_oper_only = 2;
- else if(strcasecmp(val, "masked") == 0)
+ else if(rb_strcasecmp(val, "masked") == 0)
ConfigFileEntry.stats_k_oper_only = 1;
- else if(strcasecmp(val, "no") == 0)
+ else if(rb_strcasecmp(val, "no") == 0)
ConfigFileEntry.stats_k_oper_only = 0;
else
conf_report_error("Invalid setting '%s' for general::stats_k_oper_only.", val);
{
char *val = data;
- if(strcasecmp(val, "yes") == 0)
+ if(rb_strcasecmp(val, "yes") == 0)
ConfigFileEntry.stats_i_oper_only = 2;
- else if(strcasecmp(val, "masked") == 0)
+ else if(rb_strcasecmp(val, "masked") == 0)
ConfigFileEntry.stats_i_oper_only = 1;
- else if(strcasecmp(val, "no") == 0)
+ else if(rb_strcasecmp(val, "no") == 0)
ConfigFileEntry.stats_i_oper_only = 0;
else
conf_report_error("Invalid setting '%s' for general::stats_i_oper_only.", val);
{
char *method = data;
- if (!strcasecmp(method, "sha1"))
- ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_SHA1;
- else if (!strcasecmp(method, "sha256"))
- ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_SHA256;
- else if (!strcasecmp(method, "sha512"))
- ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_SHA512;
+ if (!rb_strcasecmp(method, CERTFP_NAME_CERT_SHA1))
+ ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_CERT_SHA1;
+ else if (!rb_strcasecmp(method, CERTFP_NAME_CERT_SHA256))
+ ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_CERT_SHA256;
+ else if (!rb_strcasecmp(method, CERTFP_NAME_CERT_SHA512))
+ ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_CERT_SHA512;
+ else if (!rb_strcasecmp(method, CERTFP_NAME_SPKI_SHA256))
+ ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_SPKI_SHA256;
+ else if (!rb_strcasecmp(method, CERTFP_NAME_SPKI_SHA512))
+ ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_SPKI_SHA512;
else
{
- ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_SHA1;
+ ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_CERT_SHA1;
conf_report_error("Ignoring general::certfp_method -- bogus certfp method %s", method);
}
}
yy_alias->name = rb_strdup(conf_cur_block_name);
yy_alias->flags = 0;
- yy_alias->hits = 0;
return 0;
}
for (; args; args = args->next)
{
- if (!strcasecmp(args->v.string, "ipv4"))
+ if (!rb_strcasecmp(args->v.string, "ipv4"))
yy_blacklist_iptype |= IPTYPE_IPV4;
- else if (!strcasecmp(args->v.string, "ipv6"))
+ else if (!rb_strcasecmp(args->v.string, "ipv6"))
yy_blacklist_iptype |= IPTYPE_IPV6;
else
conf_report_error("blacklist::type has unknown address family %s",
yy_opm_address_ipv4 = yy_opm_address_ipv6 = NULL;
yy_opm_port_ipv4 = yy_opm_port_ipv6 = yy_opm_timeout = 0;
delete_opm_proxy_scanner_all();
+ delete_opm_listener_all();
return 0;
}
if(yy_opm_port_ipv4 > 0)
{
if(yy_opm_address_ipv4 != NULL)
- create_opm_listener(yy_opm_address_ipv4, yy_opm_port_ipv4);
+ conf_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)))
+ if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.bind4, ip, sizeof(ip)))
conf_report_error("No opm::listen_ipv4 nor serverinfo::vhost directive; cannot listen on IPv4");
else
- create_opm_listener(ip, yy_opm_port_ipv4);
+ conf_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);
+ conf_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)))
+ if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.bind6, ip, sizeof(ip)))
conf_report_error("No opm::listen_ipv6 nor serverinfo::vhost directive; cannot listen on IPv6");
else
- create_opm_listener(ip, yy_opm_port_ipv6);
+ conf_create_opm_listener(ip, yy_opm_port_ipv6);
}
}
const char *confstr = (ipv6 ? "opm::listen_ipv6" : "opm::listen_ipv4");
char *ip = data;
- if(!rb_inet_pton_sock(ip, (struct sockaddr *)&addr))
+ if(!rb_inet_pton_sock(ip, &addr))
{
conf_report_error("%s is an invalid address: %s", confstr, ip);
return;
if(ipv6)
{
-#ifdef RB_IPV6
if(GET_SS_FAMILY(&addr) != AF_INET6)
{
conf_report_error("%s is of the wrong address type: %s", confstr, ip);
}
yy_opm_address_ipv6 = rb_strdup(ip);
-#else
- conf_report_error("%s requires IPv6 support in your ircd", confstr, ip);
- return;
-#endif
}
else
{
int port = *((int *)data);
const char *confstr = (ipv6 ? "opm::port_ipv6" : "opm::port_ipv4");
-#ifndef RB_IPV6
- if(ipv6)
- {
- conf_report_error("%s requires IPv6 support in your ircd", confstr);
- return;
- }
-#endif
-
if(port > 65535 || port <= 0)
{
conf_report_error("%s is out of range: %d", confstr, port);
conf_report_error("%s argument is not an integer -- ignoring.", node);
continue;
}
-
+
if(args->v.number > 65535 || args->v.number <= 0)
{
conf_report_error("%s argument is not an integer between 1 and 65535 -- ignoring.", node);
{
{ "ping_time", CF_TIME, conf_set_class_ping_time, 0, NULL },
{ "cidr_ipv4_bitlen", CF_INT, conf_set_class_cidr_ipv4_bitlen, 0, NULL },
-#ifdef RB_IPV6
{ "cidr_ipv6_bitlen", CF_INT, conf_set_class_cidr_ipv6_bitlen, 0, NULL },
-#endif
{ "number_per_cidr", CF_INT, conf_set_class_number_per_cidr, 0, NULL },
{ "number_per_ip", CF_INT, conf_set_class_number_per_ip, 0, NULL },
{ "number_per_ip_global", CF_INT,conf_set_class_number_per_ip_global, 0, NULL },
{ "compression_level", CF_INT, conf_set_general_compression_level, 0, NULL },
{ "havent_read_conf", CF_YESNO, conf_set_general_havent_read_conf, 0, NULL },
{ "hide_error_messages",CF_STRING, conf_set_general_hide_error_messages,0, NULL },
- { "kline_delay", CF_TIME, conf_set_general_kline_delay, 0, NULL },
{ "stats_k_oper_only", CF_STRING, conf_set_general_stats_k_oper_only, 0, NULL },
{ "stats_i_oper_only", CF_STRING, conf_set_general_stats_i_oper_only, 0, NULL },
{ "default_umodes", CF_QSTRING, conf_set_general_default_umodes, 0, NULL },
add_conf_item("listen", "wsock", CF_YESNO, conf_set_listen_wsock);
add_conf_item("listen", "port", CF_INT | CF_FLIST, conf_set_listen_port);
add_conf_item("listen", "sslport", CF_INT | CF_FLIST, conf_set_listen_sslport);
+ add_conf_item("listen", "sctp_port", CF_INT | CF_FLIST, conf_set_listen_sctp_port);
+ add_conf_item("listen", "sctp_sslport", CF_INT | CF_FLIST, conf_set_listen_sctp_sslport);
add_conf_item("listen", "ip", CF_QSTRING, conf_set_listen_address);
add_conf_item("listen", "host", CF_QSTRING, conf_set_listen_address);