#include "wsproc.h"
#include "privilege.h"
#include "chmode.h"
+#include "certfp.h"
#define CF_TYPE(x) ((x) & CF_MTYPE)
static char *yy_opm_address_ipv6 = NULL;
static uint16_t yy_opm_port_ipv4 = 0;
static uint16_t yy_opm_port_ipv6 = 0;
+static int yy_opm_timeout = 0;
static rb_dlink_list yy_opm_scanner_list;
static char *yy_privset_extends = NULL;
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, (struct sockaddr *)&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, (struct sockaddr *)&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;
+ ServerInfo.bind6 = addr;
#else
conf_report_error("Warning -- ignoring serverinfo::vhost6 -- IPv6 support not available.");
#endif
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);
}
{ "kline", SHARED_PKLINE|SHARED_TKLINE },
{ "xline", SHARED_PXLINE|SHARED_TXLINE },
{ "resv", SHARED_PRESV|SHARED_TRESV },
- { "dline", SHARED_PDLINE|SHARED_TDLINE },
- { "tdline", SHARED_TDLINE },
- { "pdline", SHARED_PDLINE },
+ { "dline", SHARED_PDLINE|SHARED_TDLINE },
+ { "tdline", SHARED_TDLINE },
+ { "pdline", SHARED_PDLINE },
{ "undline", SHARED_UNDLINE },
{ "tkline", SHARED_TKLINE },
{ "unkline", SHARED_UNKLINE },
{
rb_free(listener_address);
listener_address = NULL;
+ yy_wsock = 0;
+ yy_defer_accept = 0;
return 0;
}
{
rb_free(listener_address);
listener_address = NULL;
+ yy_wsock = 0;
+ yy_defer_accept = 0;
return 0;
}
{
if (!ssl)
{
- conf_report_warning("listener 'ANY/%d': support for plaintext listeners may be removed in a future release per RFC 7194. "
+ conf_report_warning("listener 'ANY/%d': support for plaintext listeners may be removed in a future release per RFCs 7194 & 7258. "
"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, yy_wsock);
if (!ssl)
{
- conf_report_warning("listener '%s/%d': support for plaintext listeners may be removed in a future release per RFC 7194. "
+ conf_report_warning("listener '%s/%d': support for plaintext listeners may be removed in a future release per RFCs 7194 & 7258. "
"It is suggested that users be migrated to SSL/TLS connections.", listener_address, args->v.number);
}
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
+#ifdef RB_IPV6
+ && GET_SS_FAMILY(&yy_server->connect6) != AF_INET6
+#endif
+ )
{
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, (struct sockaddr *)&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;
+ }
+#ifdef RB_IPV6
+ else if(GET_SS_FAMILY(&addr) == AF_INET6)
+ {
+ yy_server->connect6 = addr;
+ }
+#endif
+ 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, (struct sockaddr *)&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;
+ }
+#ifdef RB_IPV6
+ else if(GET_SS_FAMILY(&addr) == AF_INET6)
{
- conf_report_error("Invalid IP address for server connect vhost (%s)",
- (char *) data);
+ yy_server->bind6 = addr;
+ }
+#endif
+ else
+ {
+ 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
{
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);
{
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",
conf_begin_opm(struct TopConf *tc)
{
yy_opm_address_ipv4 = yy_opm_address_ipv6 = NULL;
- yy_opm_port_ipv4 = yy_opm_port_ipv6 = 0;
+ yy_opm_port_ipv4 = yy_opm_port_ipv6 = yy_opm_timeout = 0;
+ delete_opm_proxy_scanner_all();
+ delete_opm_listener_all();
return 0;
}
rb_dlink_node *ptr, *nptr;
bool fail = false;
- if(!rb_dlink_list_length(&yy_opm_scanner_list))
+ if(rb_dlink_list_length(&yy_opm_scanner_list) == 0)
{
- conf_report_error("No opm scanners configured, disabling opm.");
+ conf_report_error("No opm scanners configured -- disabling opm.");
fail = true;
goto end;
}
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);
}
}
/* If there's no listeners... */
fail = (yy_opm_port_ipv4 == 0 || yy_opm_port_ipv6 == 0);
+ if(!fail && yy_opm_timeout > 0 && yy_opm_timeout < 60)
+ /* Send timeout */
+ set_authd_timeout("opm_timeout", yy_opm_timeout);
+ else if(fail)
+ conf_report_error("No opm listeners -- disabling");
+ else if(yy_opm_timeout <= 0 || yy_opm_timeout >= 60)
+ conf_report_error("opm::timeout value is invalid -- ignoring");
end:
RB_DLINK_FOREACH_SAFE(ptr, nptr, yy_opm_scanner_list.head)
rb_free(scanner);
}
+ if(!fail)
+ opm_check_enable(true);
+
rb_free(yy_opm_address_ipv4);
rb_free(yy_opm_address_ipv6);
return 0;
}
+static void
+conf_set_opm_timeout(void *data)
+{
+ int timeout = *((int *)data);
+
+ if(timeout <= 0 || timeout > 60)
+ {
+ conf_report_error("opm::timeout value %d is bogus, ignoring", timeout);
+ return;
+ }
+
+ yy_opm_timeout = timeout;
+}
static void
conf_set_opm_listen_address_both(void *data, bool ipv6)
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);
conf_set_opm_scan_ports_all(data, "opm::httpconnect_ports", "httpconnect");
}
+static void
+conf_set_opm_scan_ports_httpsconnect(void *data)
+{
+ conf_set_opm_scan_ports_all(data, "opm::httpsconnect_ports", "httpsconnect");
+}
+
/* public functions */
if((cf = find_conf_item(tc, item)) == NULL)
{
conf_report_error
- ("Non-existant configuration setting %s::%s.", tc->tc_name, (char *) item);
+ ("Non-existent configuration setting %s::%s.", tc->tc_name, (char *) item);
return -1;
}
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", "timeout", CF_INT, conf_set_opm_timeout);
add_conf_item("opm", "listen_ipv4", CF_QSTRING, conf_set_opm_listen_address_ipv4);
add_conf_item("opm", "listen_ipv6", CF_QSTRING, conf_set_opm_listen_address_ipv6);
add_conf_item("opm", "port_v4", CF_INT, conf_set_opm_listen_port_ipv4);
add_conf_item("opm", "socks4_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_socks4);
add_conf_item("opm", "socks5_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_socks5);
add_conf_item("opm", "httpconnect_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_httpconnect);
+ add_conf_item("opm", "httpsconnect_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_httpsconnect);
}