mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-01 03:16:38 +02:00
Add HOOKTYPE_IS_HANDSHAKE_FINISHED: if a module returns 0 then register_user()
will not be called. This is used, for example, by m_cap when the CAP LS handshake is still in progress. Modules can add their own requirements as they see fit. Note that, as for (CAP) functionality, this adds nothing new, it just implements it in a cleaner way, rather than all over the place, like in UnrealIRCd 4.x.
This commit is contained in:
+1
-1
@@ -829,7 +829,7 @@ extern int badword_config_process(ConfigItem_badword *ca, char *str);
|
||||
extern void badword_config_free(ConfigItem_badword *ca);
|
||||
extern char *badword_config_check_regex(char *s, int fastsupport, int check_broadness);
|
||||
extern long ClientCapabilityBit(const char *token);
|
||||
extern int user_ready_for_register(aClient *sptr);
|
||||
extern int is_handshake_finished(aClient *sptr);
|
||||
extern void SetCapability(aClient *acptr, const char *token);
|
||||
extern void ClearCapability(aClient *acptr, const char *token);
|
||||
extern void new_message(aClient *sender, MessageTag *recv_mtags, MessageTag **mtag_list);
|
||||
|
||||
+4
-1
@@ -872,6 +872,7 @@ extern char *moddata_client_get(aClient *acptr, char *varname);
|
||||
#define HOOKTYPE_PRE_COMMAND 98
|
||||
#define HOOKTYPE_POST_COMMAND 99
|
||||
#define HOOKTYPE_NEW_MESSAGE 100
|
||||
#define HOOKTYPE_IS_HANDSHAKE_FINISHED 101
|
||||
|
||||
/* Adding a new hook here?
|
||||
* 1) Add the #define HOOKTYPE_.... with a new number
|
||||
@@ -979,6 +980,7 @@ int hooktype_welcome(aClient *sptr, int after_numeric);
|
||||
int hooktype_pre_command(aClient *from, MessageTag *mtags, char *buf);
|
||||
int hooktype_post_command(aClient *from, MessageTag *mtags, char *buf);
|
||||
void hooktype_new_message(aClient *sender, MessageTag *recv_mtags, MessageTag **mtag_list, char *signature);
|
||||
int hooktype_is_handshake_finished(aClient *acptr);
|
||||
|
||||
#ifdef GCC_TYPECHECKING
|
||||
#define ValidateHook(validatefunc, func) __builtin_types_compatible_p(__typeof__(func), __typeof__(validatefunc))
|
||||
@@ -1083,7 +1085,8 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum
|
||||
((hooktype == HOOKTYPE_WELCOME) && !ValidateHook(hooktype_welcome, func)) || \
|
||||
((hooktype == HOOKTYPE_PRE_COMMAND) && !ValidateHook(hooktype_pre_command, func)) || \
|
||||
((hooktype == HOOKTYPE_POST_COMMAND) && !ValidateHook(hooktype_post_command, func)) || \
|
||||
((hooktype == HOOKTYPE_NEW_MESSAGE) && !ValidateHook(hooktype_new_message, func)) ) \
|
||||
((hooktype == HOOKTYPE_NEW_MESSAGE) && !ValidateHook(hooktype_new_message, func)) || \
|
||||
((hooktype == HOOKTYPE_IS_HANDSHAKE_FINISHED) && !ValidateHook(hooktype_is_handshake_finished, func)) ) \
|
||||
_hook_error_incompatible();
|
||||
#endif /* GCC_TYPECHECKING */
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ ModuleHeader MOD_HEADER(m_cap)
|
||||
};
|
||||
|
||||
/* Forward declarations */
|
||||
int cap_is_handshake_finished(aClient *acptr);
|
||||
int cap_never_visible(aClient *acptr);
|
||||
|
||||
/* Variables */
|
||||
@@ -93,6 +94,8 @@ MOD_INIT(m_cap)
|
||||
c.name = "extended-join";
|
||||
ClientCapabilityAdd(modinfo->handle, &c, &CAP_EXTENDED_JOIN);
|
||||
|
||||
HookAdd(modinfo->handle, HOOKTYPE_IS_HANDSHAKE_FINISHED, 0, cap_is_handshake_finished);
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -369,6 +372,15 @@ int cap_never_visible(aClient *acptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Is our handshake done? */
|
||||
int cap_is_handshake_finished(aClient *acptr)
|
||||
{
|
||||
if (HasCapabilityFast(acptr, CAP_IN_PROGRESS))
|
||||
return 0; /* We are in CAP LS stage, waiting for a CAP END */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
CMD_FUNC(m_cap)
|
||||
{
|
||||
struct clicap_cmd *cmd;
|
||||
|
||||
@@ -1095,7 +1095,7 @@ CMD_FUNC(m_nick)
|
||||
}
|
||||
/* This had to be copied here to avoid problems.. */
|
||||
strlcpy(sptr->name, nick, sizeof(sptr->name));
|
||||
if (user_ready_for_register(sptr))
|
||||
if (is_handshake_finished(sptr))
|
||||
{
|
||||
/*
|
||||
** USER already received, now we have NICK.
|
||||
|
||||
@@ -135,7 +135,7 @@ CMD_FUNC(m_nospoof)
|
||||
sendto_one(sptr, NULL, ":IRC!IRC@%s PRIVMSG %s :\1VERSION\1",
|
||||
me.name, sptr->name);
|
||||
|
||||
if (user_ready_for_register(sptr))
|
||||
if (is_handshake_finished(sptr))
|
||||
return register_user(cptr, sptr, sptr->name,
|
||||
sptr->user->username, NULL, NULL, NULL);
|
||||
return 0;
|
||||
|
||||
@@ -169,7 +169,7 @@ CMD_FUNC(m_user)
|
||||
|
||||
strlcpy(sptr->info, realname, sizeof(sptr->info));
|
||||
if (*sptr->name &&
|
||||
(IsServer(cptr) || user_ready_for_register(cptr))
|
||||
(IsServer(cptr) || is_handshake_finished(cptr))
|
||||
)
|
||||
/* NICK and no-spoof already received, now we have USER... */
|
||||
{
|
||||
|
||||
+19
-10
@@ -835,18 +835,27 @@ void set_targmax_defaults(void)
|
||||
setmaxtargets("WATCH", MAXTARGETS_MAX); // not configurable
|
||||
}
|
||||
|
||||
/** Can register_user() be called?
|
||||
* In other words:
|
||||
* - we have a NICK
|
||||
* - we have a USER
|
||||
* - there is no client capability negotiation in progress
|
||||
* - the nospoof cookie has been received (if enabled)
|
||||
/** Is the user handshake finished and can register_user() be called?
|
||||
* This checks things like: do we have a NICK, USER, nospoof,
|
||||
* and any other things modules may add:
|
||||
* eg: the cap module checks if client capability negotiation
|
||||
* is in progress
|
||||
*/
|
||||
int user_ready_for_register(aClient *sptr)
|
||||
int is_handshake_finished(aClient *sptr)
|
||||
{
|
||||
#define PROTO_CLICAP 0x1000000
|
||||
// TEST: FIXME
|
||||
if (sptr->user && *sptr->user->username && sptr->name[0] && !CHECKPROTO(sptr, PROTO_CLICAP) && IsNotSpoof(sptr))
|
||||
Hook *h;
|
||||
int n;
|
||||
|
||||
for (h = Hooks[HOOKTYPE_IS_HANDSHAKE_FINISHED]; h; h = h->next)
|
||||
{
|
||||
n = (*(h->func.intfunc))(sptr);
|
||||
if (n == 0)
|
||||
return 0; /* We can stop already */
|
||||
}
|
||||
|
||||
/* I figured these can be here, in the core: */
|
||||
if (sptr->user && *sptr->user->username && sptr->name[0] && IsNotSpoof(sptr))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user