From 894ccd3b8d5acb0067562d26bf72228d3e617203 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Mon, 5 Nov 2012 21:48:21 -0500 Subject: [PATCH] Add a parameter to IPcheck_connect_fail() to support IAuth IP spoofing. Before, the "connected" count for the client's true IP address would be incremented but never decremented. This matches them up properly. --- ChangeLog | 15 +++++++++++++++ include/IPcheck.h | 2 +- ircd/IPcheck.c | 20 ++++++++++++++------ ircd/m_nick.c | 4 ++-- ircd/s_auth.c | 4 ++-- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 972cefe..e9291bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2012-10-15 Michael Poole + + * include/IPcheck.h (IPcheck_connect_fail): Add new 'disconnect' + parameter. This treats the failure as a disconnection from the + client's current IP address. + + * ircd/IPcheck.c (ip_registry_connect_fail): Likewise. + (IPcheck_connect_fail): Pass it through. + + * ircd/m_nick.c (m_nick): Pass zero for the new parameter. + (ms_nick): Likewise. + + * ircd/s_auth.c (preregister_user): Likewise. + (iauth_cmd_ip_address): Pass one for the new parameter. + 2012-06-20 Michael Poole * ircd/ircd_string.c (ipmask_parse): Return zero if there is junk diff --git a/include/IPcheck.h b/include/IPcheck.h index 493ef43..91693ac 100644 --- a/include/IPcheck.h +++ b/include/IPcheck.h @@ -18,7 +18,7 @@ struct irc_in_addr; */ extern void IPcheck_init(void); extern int IPcheck_local_connect(const struct irc_in_addr *ip, time_t *next_target_out); -extern void IPcheck_connect_fail(const struct Client *cptr); +extern void IPcheck_connect_fail(const struct Client *cptr, int disconnect); extern void IPcheck_connect_succeeded(struct Client *cptr); extern int IPcheck_remote_connect(struct Client *cptr, int is_burst); extern void IPcheck_disconnect(struct Client *cptr); diff --git a/ircd/IPcheck.c b/ircd/IPcheck.c index 373958e..67b3485 100644 --- a/ircd/IPcheck.c +++ b/ircd/IPcheck.c @@ -373,13 +373,20 @@ int ip_registry_check_remote(struct Client* cptr, int is_burst) * of their own. This "undoes" the effect of ip_registry_check_local() * so the client's address is not penalized for the failure. * @param[in] addr Address of rejected client. + * @param[in] disconnect If true, also count the client as disconnecting. */ -void ip_registry_connect_fail(const struct irc_in_addr *addr) +void ip_registry_connect_fail(const struct irc_in_addr *addr, int disconnect) { struct IPRegistryEntry* entry = ip_registry_find(addr); - if (entry && 0 == --entry->attempts) { - Debug((DEBUG_DNS, "IPcheck noting local connection failure for %s.", ircd_ntoa(&entry->addr))); - ++entry->attempts; + if (entry) { + if (0 == --entry->attempts) { + Debug((DEBUG_DNS, "IPcheck noting local connection failure for %s.", ircd_ntoa(&entry->addr))); + ++entry->attempts; + } + if (disconnect) { + assert(entry->connected > 0); + entry->connected--; + } } } @@ -521,11 +528,12 @@ int IPcheck_remote_connect(struct Client *cptr, int is_burst) * of their own. This "undoes" the effect of ip_registry_check_local() * so the client's address is not penalized for the failure. * @param[in] cptr Client who has been rejected. + * @param[in] disconnect If true, also count the client as disconnecting. */ -void IPcheck_connect_fail(const struct Client *cptr) +void IPcheck_connect_fail(const struct Client *cptr, int disconnect) { assert(IsIPChecked(cptr)); - ip_registry_connect_fail(&cli_ip(cptr)); + ip_registry_connect_fail(&cli_ip(cptr), disconnect); } /** Handle a client that has successfully connected. diff --git a/ircd/m_nick.c b/ircd/m_nick.c index fe13d4e..b612f86 100644 --- a/ircd/m_nick.c +++ b/ircd/m_nick.c @@ -246,7 +246,7 @@ int m_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) */ if (IsUnknown(acptr) && MyConnect(acptr)) { ServerStats->is_ref++; - IPcheck_connect_fail(acptr); + IPcheck_connect_fail(acptr, 0); exit_client(cptr, acptr, &me, "Overridden by other sign on"); return set_nick_name(cptr, sptr, nick, parc, parv); } @@ -376,7 +376,7 @@ int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) if (IsUnknown(acptr) && MyConnect(acptr)) { ServerStats->is_ref++; - IPcheck_connect_fail(acptr); + IPcheck_connect_fail(acptr, 0); exit_client(cptr, acptr, &me, "Overridden by other sign on"); return set_nick_name(cptr, sptr, nick, parc, parv); } diff --git a/ircd/s_auth.c b/ircd/s_auth.c index e250ae6..924bd50 100644 --- a/ircd/s_auth.c +++ b/ircd/s_auth.c @@ -529,7 +529,7 @@ static int preregister_user(struct Client *cptr) /* Can this ever happen? */ case ACR_BAD_SOCKET: ++ServerStats->is_ref; - IPcheck_connect_fail(cptr); + IPcheck_connect_fail(cptr, 0); return exit_client(cptr, cptr, &me, "Unknown error -- Try again"); } return 0; @@ -1828,7 +1828,7 @@ static int iauth_cmd_ip_address(struct IAuth *iauth, struct Client *cli, memcpy(&auth->original, &cli_ip(cli), sizeof(auth->original)); /* Undo original IP connection in IPcheck. */ - IPcheck_connect_fail(cli); + IPcheck_connect_fail(cli, 1); ClearIPChecked(cli); /* Update the IP and charge them as a remote connect. */ -- 2.20.1