static int opm_timeout = OPM_TIMEOUT_DEFAULT;
static bool opm_enable = false;
-#define LISTEN_IPV4 0
-#define LISTEN_IPV6 1
+enum
+{
+ LISTEN_IPV4,
+ LISTEN_IPV6,
+ LISTEN_LAST,
+};
/* IPv4 and IPv6 */
-static struct opm_listener listeners[2];
+static struct opm_listener listeners[LISTEN_LAST];
static inline protocol_t
get_protocol_from_string(const char *str)
opm_enable = false;
}
+static void
+delete_opm_listener_all(const char *key __unused, int parc __unused, const char **parv __unused)
+{
+ if(listeners[LISTEN_IPV4].F != NULL)
+ rb_close(listeners[LISTEN_IPV4].F);
+
+#ifdef RB_IPV6
+ if(listeners[LISTEN_IPV6].F != NULL)
+ rb_close(listeners[LISTEN_IPV6].F);
+#endif
+
+ memset(&listeners, 0, sizeof(listeners));
+}
+
struct auth_opts_handler opm_options[] =
{
{ "opm_timeout", 1, add_conf_opm_timeout },
{ "opm_enabled", 1, set_opm_enabled },
{ "opm_listener", 2, set_opm_listener },
+ { "opm_listener_del_all", 0, delete_opm_listener_all },
{ "opm_scanner", 2, create_opm_scanner },
{ "opm_scanner_del", 2, delete_opm_scanner },
{ "opm_scanner_del_all", 0, delete_opm_scanner_all },
#include "rb_dictionary.h"
#include "client.h"
-struct blacklist_stats
+struct BlacklistStats
{
uint8_t iptype;
unsigned int hits;
};
+struct OPMScanner
+{
+ char type[16]; /* Type of proxy */
+ uint16_t port; /* Port */
+
+ rb_dlink_node node;
+};
+
+struct OPMListener
+{
+ char ipaddr[HOSTIPLEN]; /* Listener address */
+ uint16_t port; /* Listener port */
+};
+
+enum
+{
+ LISTEN_IPV4,
+ LISTEN_IPV6,
+ LISTEN_LAST,
+};
+
extern rb_helper *authd_helper;
extern rb_dictionary *bl_stats;
+extern rb_dlink_list opm_list;
+extern struct OPMListener opm_listeners[LISTEN_LAST];
void init_authd(void);
void configure_authd(void);
bool set_authd_timeout(const char *key, int timeout);
void ident_check_enable(bool enabled);
+void conf_create_opm_listener(const char *ip, uint16_t port);
void create_opm_listener(const char *ip, uint16_t port);
-void opm_check_enable(bool enabled);
+void conf_create_opm_proxy_scanner(const char *type, uint16_t port);
void create_opm_proxy_scanner(const char *type, uint16_t port);
void delete_opm_proxy_scanner(const char *type, uint16_t port);
void delete_opm_proxy_scanner_all(void);
+void delete_opm_listener_all(void);
+void opm_check_enable(bool enabled);
#endif
rb_dictionary *bl_stats;
+rb_dlink_list opm_list;
+struct OPMListener opm_listeners[LISTEN_LAST];
+
static struct authd_cb authd_cmd_tab[256] =
{
['A'] = { cmd_accept_client, 4 },
void
configure_authd(void)
{
- /* These will do for now */
+ /* Timeouts */
set_authd_timeout("ident_timeout", GlobalSetOptions.ident_timeout);
set_authd_timeout("rdns_timeout", ConfigFileEntry.connect_timeout);
set_authd_timeout("rbl_timeout", ConfigFileEntry.connect_timeout);
+
ident_check_enable(!ConfigFileEntry.disable_auth);
+
+ /* Configure OPM */
+ if(rb_dlink_list_length(&opm_list) > 0 &&
+ (opm_listeners[LISTEN_IPV4].ipaddr[0] != '\0' ||
+ opm_listeners[LISTEN_IPV6].ipaddr[0] != '\0'))
+ {
+ rb_dlink_node *ptr;
+
+ if(opm_listeners[LISTEN_IPV4].ipaddr[0] != '\0')
+ rb_helper_write(authd_helper, "O opm_listener %s %hu",
+ opm_listeners[LISTEN_IPV4].ipaddr, opm_listeners[LISTEN_IPV4].port);
+
+#ifdef RB_IPV6
+ if(opm_listeners[LISTEN_IPV6].ipaddr[0] != '\0')
+ rb_helper_write(authd_helper, "O opm_listener %s %hu",
+ opm_listeners[LISTEN_IPV6].ipaddr, opm_listeners[LISTEN_IPV6].port);
+#endif
+
+ RB_DLINK_FOREACH(ptr, opm_list.head)
+ {
+ struct OPMScanner *scanner = ptr->data;
+ rb_helper_write(authd_helper, "O opm_scanner %s %hu",
+ scanner->type, scanner->port);
+ }
+
+ opm_check_enable(true);
+ }
+ else
+ opm_check_enable(false);
}
static void
start_authd();
configure_authd();
- rehash(false); /* FIXME - needed to reload authd configuration */
}
void
add_blacklist(const char *host, const char *reason, uint8_t iptype, rb_dlink_list *filters)
{
rb_dlink_node *ptr;
- struct blacklist_stats *stats = rb_malloc(sizeof(struct blacklist_stats));
+ struct BlacklistStats *stats = rb_malloc(sizeof(struct BlacklistStats));
char filterbuf[BUFSIZE] = "*";
size_t s = 0;
void
del_blacklist(const char *host)
{
- rb_free(rb_dictionary_delete(bl_stats, host));
+ struct BlacklistStats *stats = rb_dictionary_retrieve(bl_stats, host);
+ if(stats != NULL)
+ {
+ rb_dictionary_delete(bl_stats, host);
+ rb_free(stats);
+ }
rb_helper_write(authd_helper, "O rbl_del %s", host);
}
void
del_blacklist_all(void)
{
- struct blacklist_stats *stats;
+ struct BlacklistStats *stats;
rb_dictionary_iter iter;
RB_DICTIONARY_FOREACH(stats, &iter, bl_stats)
rb_helper_write(authd_helper, "O ident_enabled %d", enabled ? 1 : 0);
}
-/* Create an OPM listener */
+/* Create an OPM listener
+ * XXX - This is a big nasty hack, but it avoids resending duplicate data when
+ * configure_authd() is called.
+ */
+void
+conf_create_opm_listener(const char *ip, uint16_t port)
+{
+ char ipbuf[HOSTIPLEN];
+ struct OPMListener *listener;
+
+ rb_strlcpy(ipbuf, ip, sizeof(ipbuf));
+ if(ipbuf[0] == ':')
+ {
+ memmove(ipbuf + 1, ipbuf, sizeof(ipbuf) - 1);
+ ipbuf[0] = '0';
+ }
+
+ /* I am much too lazy to use rb_inet_pton and GET_SS_FAMILY for now --Elizafox */
+ listener = &opm_listeners[(strchr(ipbuf, ':') != NULL ? LISTEN_IPV6 : LISTEN_IPV4)];
+ rb_strlcpy(listener->ipaddr, ipbuf, sizeof(listener->ipaddr));
+ listener->port = port;
+}
+
void
create_opm_listener(const char *ip, uint16_t port)
{
char ipbuf[HOSTIPLEN];
+
+ /* XXX duplicated in conf_create_opm_listener */
rb_strlcpy(ipbuf, ip, sizeof(ipbuf));
if(ipbuf[0] == ':')
{
ipbuf[0] = '0';
}
- rb_helper_write(authd_helper, "O opm_listener %s %hu", ipbuf, port);
+ conf_create_opm_listener(ip, port);
+ rb_helper_write(authd_helper, "O opm_listener %s %hu", ip, port);
+}
+
+void
+delete_opm_listener_all(void)
+{
+ memset(&opm_listeners, 0, sizeof(opm_listeners));
+ rb_helper_write(authd_helper, "O opm_listener_del_all");
}
/* Disable all OPM scans */
rb_helper_write(authd_helper, "O opm_enabled %d", enabled ? 1 : 0);
}
-/* Create an OPM proxy scanner */
+/* Create an OPM proxy scanner
+ * XXX - This is a big nasty hack, but it avoids resending duplicate data when
+ * configure_authd() is called.
+ */
+void
+conf_create_opm_proxy_scanner(const char *type, uint16_t port)
+{
+ struct OPMScanner *scanner = rb_malloc(sizeof(struct OPMScanner));
+
+ rb_strlcpy(scanner->type, type, sizeof(scanner->type));
+ scanner->port = port;
+ rb_dlinkAdd(scanner, &scanner->node, &opm_list);
+}
+
void
create_opm_proxy_scanner(const char *type, uint16_t port)
{
+ conf_create_opm_proxy_scanner(type, port);
rb_helper_write(authd_helper, "O opm_scanner %s %hu", type, port);
}
void
delete_opm_proxy_scanner(const char *type, uint16_t port)
{
+ rb_dlink_node *ptr, *nptr;
+
+ RB_DLINK_FOREACH_SAFE(ptr, nptr, opm_list.head)
+ {
+ struct OPMScanner *scanner = ptr->data;
+
+ if(rb_strncasecmp(scanner->type, type, sizeof(scanner->type)) == 0 &&
+ scanner->port == port)
+ {
+ rb_dlinkDelete(ptr, &opm_list);
+ rb_free(scanner);
+ break;
+ }
+ }
+
rb_helper_write(authd_helper, "O opm_scanner_del %s %hu", type, port);
}
void
delete_opm_proxy_scanner_all(void)
{
+ rb_dlink_node *ptr, *nptr;
+
+ RB_DLINK_FOREACH_SAFE(ptr, nptr, opm_list.head)
+ {
+ struct OPMScanner *scanner = ptr->data;
+
+ rb_dlinkDelete(ptr, &opm_list);
+ rb_free(scanner);
+ }
+
rb_helper_write(authd_helper, "O opm_scanner_del_all");
}
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)))
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)))
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);
}
}
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);