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:
parent
5eb8ce0679
commit
5e9a3f8674
6 changed files with 175 additions and 21 deletions
|
@ -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 },
|
||||
|
|
|
@ -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
|
||||
|
|
126
ircd/authproc.c
126
ircd/authproc.c
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue