Change the way authd configures opm

It's a bit of a hack, but better than before. Rather than rehashing
(which could get us into an endless loop), we now segregate the
configuration phase (creating entries ircd-side in case we restart authd
later) and sending phases (when configure_authd() is called). Since we
have to call configure_authd() no matter what (to send timeouts etc.)
and we have to send this data to configure authd anyway, and sending
duplicate data is bad, this is the only way I can think of for now.
This commit is contained in:
Elizabeth Myers 2016-04-12 09:33:51 -05:00
parent 5eb8ce0679
commit 5e9a3f8674
No known key found for this signature in database
GPG key ID: 1A10EF78D83E317B
6 changed files with 175 additions and 21 deletions

View file

@ -98,11 +98,15 @@ static bool create_listener(const char *ip, uint16_t port);
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)
@ -891,12 +895,27 @@ delete_opm_scanner_all(const char *key __unused, int parc __unused, const char *
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 },

View file

@ -30,15 +30,38 @@
#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);
@ -58,10 +81,13 @@ void del_blacklist_all(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

View file

@ -69,6 +69,9 @@ static struct ev_entry *timeout_ev;
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 },
@ -316,11 +319,41 @@ init_authd(void)
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
@ -346,7 +379,6 @@ restart_authd_cb(rb_helper * helper)
start_authd();
configure_authd();
rehash(false); /* FIXME - needed to reload authd configuration */
}
void
@ -507,7 +539,7 @@ 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;
@ -541,7 +573,12 @@ add_blacklist(const char *host, const char *reason, uint8_t iptype, rb_dlink_lis
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);
}
@ -550,7 +587,7 @@ del_blacklist(const char *host)
void
del_blacklist_all(void)
{
struct blacklist_stats *stats;
struct BlacklistStats *stats;
rb_dictionary_iter iter;
RB_DICTIONARY_FOREACH(stats, &iter, bl_stats)
@ -580,11 +617,16 @@ ident_check_enable(bool enabled)
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
create_opm_listener(const char *ip, uint16_t port)
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] == ':')
{
@ -592,7 +634,34 @@ create_opm_listener(const char *ip, uint16_t port)
ipbuf[0] = '0';
}
rb_helper_write(authd_helper, "O opm_listener %s %hu", ipbuf, port);
/* 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] == ':')
{
memmove(ipbuf + 1, ipbuf, sizeof(ipbuf) - 1);
ipbuf[0] = '0';
}
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 */
@ -602,21 +671,60 @@ opm_check_enable(bool enabled)
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");
}

View file

@ -2043,6 +2043,7 @@ conf_begin_opm(struct TopConf *tc)
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;
}
@ -2062,28 +2063,28 @@ 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);
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);
}
}

View file

@ -215,7 +215,7 @@ authd_check(struct Client *client_p, struct Client *source_p)
{
case 'B': /* Blacklists */
{
struct blacklist_stats *stats;
struct BlacklistStats *stats;
char *blacklist = source_p->preClient->auth.data;
if((stats = rb_dictionary_retrieve(bl_stats, blacklist)) != NULL)

View file

@ -753,7 +753,7 @@ static void
stats_dnsbl(struct Client *source_p)
{
rb_dictionary_iter iter;
struct blacklist_stats *stats;
struct BlacklistStats *stats;
RB_DICTIONARY_FOREACH(stats, &iter, bl_stats)
{