Add a parameter to IPcheck_connect_fail() to support IAuth IP spoofing.
authorMichael Poole <mdpoole@troilus.org>
Tue, 6 Nov 2012 02:48:21 +0000 (21:48 -0500)
committerMichael Poole <mdpoole@troilus.org>
Tue, 6 Nov 2012 02:48:21 +0000 (21:48 -0500)
Before, the "connected" count for the client's true IP address would be
incremented but never decremented.  This matches them up properly.

ChangeLog
include/IPcheck.h
ircd/IPcheck.c
ircd/m_nick.c
ircd/s_auth.c

index 972cefe2e9c9819bda83adb2a56f8dddec48be99..e9291bb2865c361c62d972b335ccb85f5541f55d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2012-10-15  Michael Poole <mdpoole@troilus.org>
+
+       * 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 <mdpoole@troilus.org>
 
        * ircd/ircd_string.c (ipmask_parse): Return zero if there is junk
index 493ef4367fe0812721d0136ac6bfb68d8e73f106..91693ac09a18b6c52cc9d2b6977cbfcfc6e80e34 100644 (file)
@@ -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);
index 373958e9dc030eb7b6e0af3f9f99596c4c398ac4..67b34851cb8fe0bbe4ce905040c4ff1179e81c83 100644 (file)
@@ -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.
index fe13d4ecb2722f8214cfea7d746bee92de054f8b..b612f8672b9e0cd42c4002b41c81c69589d04663 100644 (file)
@@ -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);
   }
index e250ae6736ef3a9348f32fd097e11c8d0bf77d71..924bd50ab13dcc36df46936301348155a327312d 100644 (file)
@@ -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. */