From f3d827c577c74a6d6084fa093491eb35ddedcf21 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Mon, 17 Jan 2022 07:55:16 +0100 Subject: [PATCH] Add HOOKTYPE_IP_CHANGE and call it when the IP address changes. Eg for WEBIRC or other proxy. This does not yet fix any problem, it just changes the way things are called. More to follow. --- include/modules.h | 19 +++++++++++++++---- src/modules/blacklist.c | 8 ++++++++ src/modules/tkl.c | 8 ++++++++ src/modules/webirc.c | 12 +++--------- src/modules/websocket.c | 15 +++++---------- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/include/modules.h b/include/modules.h index c97a3bb4b..75f996aaf 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1157,6 +1157,8 @@ extern void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, l #define HOOKTYPE_REALNAME_CHANGED 109 /** See hooktype_can_set_topic() */ #define HOOKTYPE_CAN_SET_TOPIC 110 +/** See hooktype_ip_change() */ +#define HOOKTYPE_IP_CHANGE 111 /* Adding a new hook here? * 1) Add the #define HOOKTYPE_.... with a new number * 2) Add a hook prototype (see below) @@ -2127,14 +2129,22 @@ int hooktype_post_remote_nickchange(Client *client, MessageTag *mtags, const cha * @param oldhost Old hostname of the client * @return The return value is ignored (use return 0) */ - -int hooktype_realname_changed(Client *client, const char *oldinfo); +int hooktype_userhost_changed(Client *client, const char *olduser, const char *oldhost); + /** Called when user realname has changed. * @param client The client whose realname has changed * @param oldinfo Old realname of the client * @return The return value is ignored (use return 0) */ -int hooktype_userhost_changed(Client *client, const char *olduser, const char *oldhost); +int hooktype_realname_changed(Client *client, const char *oldinfo); + +/** Called when changing IP (eg due to PROXY/WEBIRC/etc). + * @param client The client whose IP has changed + * @param oldip Old IP of the client + * @return The return value is ignored (use return 0) + */ +int hooktype_ip_change(Client *client, const char *oldip); + /** @} */ #ifdef GCC_TYPECHECKING @@ -2248,7 +2258,8 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum ((hooktype == HOOKTYPE_POST_LOCAL_NICKCHANGE) && !ValidateHook(hooktype_post_local_nickchange, func)) || \ ((hooktype == HOOKTYPE_POST_REMOTE_NICKCHANGE) && !ValidateHook(hooktype_post_remote_nickchange, func)) || \ ((hooktype == HOOKTYPE_USERHOST_CHANGED) && !ValidateHook(hooktype_userhost_changed, func)) || \ - ((hooktype == HOOKTYPE_REALNAME_CHANGED) && !ValidateHook(hooktype_realname_changed, func)) )\ + ((hooktype == HOOKTYPE_REALNAME_CHANGED) && !ValidateHook(hooktype_realname_changed, func)) || \ + ((hooktype == HOOKTYPE_IP_CHANGE) && !ValidateHook(hooktype_ip_change, func)) ) \ _hook_error_incompatible(); #endif /* GCC_TYPECHECKING */ diff --git a/src/modules/blacklist.c b/src/modules/blacklist.c index 696b8fa81..3cbdec9f7 100644 --- a/src/modules/blacklist.c +++ b/src/modules/blacklist.c @@ -99,6 +99,7 @@ void blacklist_free_conf(void); void delete_blacklist_block(Blacklist *e); void blacklist_md_free(ModData *md); int blacklist_handshake(Client *client); +int blacklist_ip_change(Client *client, const char *oldip); int blacklist_quit(Client *client, MessageTag *mtags, const char *comment); int blacklist_preconnect(Client *client); void blacklist_resolver_callback(void *arg, int status, int timeouts, struct hostent *he); @@ -146,6 +147,7 @@ MOD_INIT() HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, blacklist_config_run); HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, blacklist_handshake); + HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, 0, blacklist_ip_change); HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 0, blacklist_preconnect); HookAdd(modinfo->handle, HOOKTYPE_REHASH, 0, blacklist_rehash); HookAdd(modinfo->handle, HOOKTYPE_REHASH_COMPLETE, 0, blacklist_rehash_complete); @@ -553,6 +555,12 @@ int blacklist_handshake(Client *client) return 0; } +int blacklist_ip_change(Client *client, const char *oldip) +{ + blacklist_start_check(client); + return 0; +} + int blacklist_start_check(Client *client) { Blacklist *bl; diff --git a/src/modules/tkl.c b/src/modules/tkl.c index 1e70ba6fa..7bc96b98f 100644 --- a/src/modules/tkl.c +++ b/src/modules/tkl.c @@ -41,6 +41,7 @@ int tkl_config_test_except(ConfigFile *, ConfigEntry *, int, int *); int tkl_config_run_except(ConfigFile *, ConfigEntry *, int); int tkl_config_test_set(ConfigFile *, ConfigEntry *, int, int *); int tkl_config_run_set(ConfigFile *, ConfigEntry *, int); +int tkl_ip_change(Client *client, const char *oldip); CMD_FUNC(cmd_gline); CMD_FUNC(cmd_shun); CMD_FUNC(cmd_tempshun); @@ -213,6 +214,7 @@ MOD_INIT() HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_ban); HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_except); HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_set); + HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, 2000000000, tkl_ip_change); CommandAdd(modinfo->handle, "GLINE", cmd_gline, 3, CMD_OPER); CommandAdd(modinfo->handle, "SHUN", cmd_shun, 3, CMD_OPER); CommandAdd(modinfo->handle, "TEMPSHUN", cmd_tempshun, 2, CMD_OPER); @@ -952,6 +954,12 @@ char *spamfilter_id(TKL *tk) return buf; } +int tkl_ip_change(Client *client, const char *oldip) +{ + check_banned(client, 0); + return 0; +} + /** GLINE - Global kline. ** Syntax: /gline [+|-]u@h mask time :reason ** diff --git a/src/modules/webirc.c b/src/modules/webirc.c index 373761d71..da4093fe0 100644 --- a/src/modules/webirc.c +++ b/src/modules/webirc.c @@ -336,6 +336,7 @@ ConfigItem_webirc *find_webirc(Client *client, const char *password, WEBIRCType /* Does the CGI:IRC host spoofing work */ void dowebirc(Client *client, const char *ip, const char *host, const char *options) { + char oldip[64]; char scratch[64]; if (IsWEBIRC(client)) @@ -357,6 +358,7 @@ void dowebirc(Client *client, const char *ip, const char *host, const char *opti } /* STEP 2: Update GetIP() */ + strlcpy(oldip, client->ip, sizeof(oldip)); safe_strdup(client->ip, ip); /* STEP 3: Update client->local->hostp */ @@ -397,15 +399,7 @@ void dowebirc(Client *client, const char *ip, const char *host, const char *opti } } - /* blacklist_start_check() */ - if (RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK] != NULL) - RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK]->func.intfunc(client); - - /* Check (g)zlines right now; these are normally checked upon accept(), - * but since we know the IP only now after PASS/WEBIRC, we have to check - * here again... - */ - check_banned(client, 0); + RunHook(HOOKTYPE_IP_CHANGE, client, oldip); } /* WEBIRC "cgiirc" [:option1 [option2...]]*/ diff --git a/src/modules/websocket.c b/src/modules/websocket.c index 73c9fcc14..111b0e48e 100644 --- a/src/modules/websocket.c +++ b/src/modules/websocket.c @@ -686,6 +686,9 @@ int websocket_handshake_valid(Client *client) } if (WSU(client)->forwarded) { + struct HTTPForwardedHeader *forwarded; + char oldip[64]; + /* check for source ip */ if (BadPtr(client->local->listener->websocket_forward) || !websocket_ip_compare(client->local->listener->websocket_forward, client->ip)) { @@ -694,7 +697,6 @@ int websocket_handshake_valid(Client *client) return 0; } /* parse the header */ - struct HTTPForwardedHeader *forwarded; forwarded = websocket_parse_forwarded_header(WSU(client)->forwarded); /* check header values */ if (!is_valid_ip(forwarded->ip)) @@ -705,6 +707,7 @@ int websocket_handshake_valid(Client *client) } /* store data */ WSU(client)->secure = forwarded->secure; + strlcpy(oldip, client->ip, sizeof(oldip)); safe_strdup(client->ip, forwarded->ip); /* Update client->local->hostp */ strlcpy(client->local->sockhost, forwarded->ip, sizeof(client->local->sockhost)); /* in case dns lookup fails or is disabled */ @@ -733,15 +736,7 @@ int websocket_handshake_valid(Client *client) /* Race condition detected, DNS has been done, continue with auth */ } } - /* blacklist_start_check() */ - if (RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK] != NULL) - RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK]->func.intfunc(client); - - /* Check (g)zlines right now; these are normally checked upon accept(), - * but since we know the IP only now after PASS/WEBIRC, we have to check - * here again... - */ - check_banned(client, 0); + RunHook(HOOKTYPE_IP_CHANGE, client, oldip); } return 1; }