m_sasl: check if the agent is present after every client_exit
When a server disconnects the client_exit hook will only be called once but there could be multiple servers and clients behind that server. After any client exits, check if the agent is still present.
This commit is contained in:
parent
f515fa9382
commit
03f04cd80e
4 changed files with 74 additions and 18 deletions
|
@ -25,6 +25,7 @@ extern int h_burst_finished;
|
|||
extern int h_server_introduced;
|
||||
extern int h_server_eob;
|
||||
extern int h_client_exit;
|
||||
extern int h_after_client_exit;
|
||||
extern int h_umode_changed;
|
||||
extern int h_new_local_user;
|
||||
extern int h_new_remote_user;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* modules/m_sasl.c
|
||||
* Copyright (C) 2006 Michael Tharp <gxti@partiallystapled.com>
|
||||
* Copyright (C) 2006 charybdis development team
|
||||
* Copyright (C) 2016 ChatLounge IRC Network Development Team
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
@ -49,8 +50,12 @@ static int me_sasl(struct Client *, struct Client *, int, const char **);
|
|||
static void abort_sasl(struct Client *);
|
||||
static void abort_sasl_exit(hook_data_client_exit *);
|
||||
|
||||
static void advertise_sasl(struct Client *);
|
||||
static void advertise_sasl_exit(hook_data_client_exit *);
|
||||
static void advertise_sasl_cap(int);
|
||||
static void advertise_sasl_new(struct Client *);
|
||||
static void advertise_sasl_exit(void *);
|
||||
static void advertise_sasl_config(void *);
|
||||
|
||||
static int sasl_agent_present = 0;
|
||||
|
||||
struct Message authenticate_msgtab = {
|
||||
"AUTHENTICATE", 0, 0, 0, MFLG_SLOW,
|
||||
|
@ -67,12 +72,38 @@ mapi_clist_av1 sasl_clist[] = {
|
|||
mapi_hfn_list_av1 sasl_hfnlist[] = {
|
||||
{ "new_local_user", (hookfn) abort_sasl },
|
||||
{ "client_exit", (hookfn) abort_sasl_exit },
|
||||
{ "new_remote_user", (hookfn) advertise_sasl },
|
||||
{ "client_exit", (hookfn) advertise_sasl_exit },
|
||||
{ "new_remote_user", (hookfn) advertise_sasl_new },
|
||||
{ "after_client_exit", (hookfn) advertise_sasl_exit },
|
||||
{ "conf_read_end", (hookfn) advertise_sasl_config },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
DECLARE_MODULE_AV1(sasl, NULL, NULL, sasl_clist, NULL, sasl_hfnlist, "$Revision: 1409 $");
|
||||
static int
|
||||
sasl_visible(void)
|
||||
{
|
||||
struct Client *agent_p = NULL;
|
||||
|
||||
if (ConfigFileEntry.sasl_service)
|
||||
agent_p = find_named_client(ConfigFileEntry.sasl_service);
|
||||
|
||||
return agent_p != NULL && IsService(agent_p);
|
||||
}
|
||||
|
||||
static int
|
||||
_modinit(void)
|
||||
{
|
||||
sasl_agent_present = 0;
|
||||
advertise_sasl_config(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_moddeinit(void)
|
||||
{
|
||||
advertise_sasl_cap(0);
|
||||
}
|
||||
|
||||
DECLARE_MODULE_AV1(sasl, _modinit, _moddeinit, sasl_clist, NULL, sasl_hfnlist, "$Revision: 1409 $");
|
||||
|
||||
static int
|
||||
m_authenticate(struct Client *client_p, struct Client *source_p,
|
||||
|
@ -261,7 +292,20 @@ abort_sasl_exit(hook_data_client_exit *data)
|
|||
}
|
||||
|
||||
static void
|
||||
advertise_sasl(struct Client *client_p)
|
||||
advertise_sasl_cap(int available)
|
||||
{
|
||||
if (sasl_agent_present != available) {
|
||||
if (available) {
|
||||
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * NEW :sasl", me.name);
|
||||
} else {
|
||||
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * DEL :sasl", me.name);
|
||||
}
|
||||
sasl_agent_present = available;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
advertise_sasl_new(struct Client *client_p)
|
||||
{
|
||||
if (!ConfigFileEntry.sasl_service)
|
||||
return;
|
||||
|
@ -269,17 +313,22 @@ advertise_sasl(struct Client *client_p)
|
|||
if (irccmp(client_p->name, ConfigFileEntry.sasl_service))
|
||||
return;
|
||||
|
||||
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * NEW :sasl", me.name);
|
||||
advertise_sasl_cap(IsService(client_p));
|
||||
}
|
||||
|
||||
static void
|
||||
advertise_sasl_exit(hook_data_client_exit *data)
|
||||
advertise_sasl_exit(void *ignored)
|
||||
{
|
||||
if (!ConfigFileEntry.sasl_service)
|
||||
return;
|
||||
|
||||
if (irccmp(data->target->name, ConfigFileEntry.sasl_service))
|
||||
return;
|
||||
|
||||
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * DEL :sasl", me.name);
|
||||
if (sasl_agent_present) {
|
||||
advertise_sasl_cap(sasl_visible());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
advertise_sasl_config(void *ignored)
|
||||
{
|
||||
advertise_sasl_cap(sasl_visible());
|
||||
}
|
||||
|
|
16
src/client.c
16
src/client.c
|
@ -1568,6 +1568,8 @@ exit_client(struct Client *client_p, /* The local client originating the
|
|||
const char *comment /* Reason for the exit */
|
||||
)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
hook_data_client_exit hdata;
|
||||
if(IsClosing(source_p))
|
||||
return -1;
|
||||
|
@ -1588,23 +1590,25 @@ exit_client(struct Client *client_p, /* The local client originating the
|
|||
{
|
||||
/* Local clients of various types */
|
||||
if(IsPerson(source_p))
|
||||
return exit_local_client(client_p, source_p, from, comment);
|
||||
ret = exit_local_client(client_p, source_p, from, comment);
|
||||
else if(IsServer(source_p))
|
||||
return exit_local_server(client_p, source_p, from, comment);
|
||||
ret = exit_local_server(client_p, source_p, from, comment);
|
||||
/* IsUnknown || IsConnecting || IsHandShake */
|
||||
else if(!IsReject(source_p))
|
||||
return exit_unknown_client(client_p, source_p, from, comment);
|
||||
ret = exit_unknown_client(client_p, source_p, from, comment);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remotes */
|
||||
if(IsPerson(source_p))
|
||||
return exit_remote_client(client_p, source_p, from, comment);
|
||||
ret = exit_remote_client(client_p, source_p, from, comment);
|
||||
else if(IsServer(source_p))
|
||||
return exit_remote_server(client_p, source_p, from, comment);
|
||||
ret = exit_remote_server(client_p, source_p, from, comment);
|
||||
}
|
||||
|
||||
return -1;
|
||||
call_hook(h_after_client_exit, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -59,6 +59,7 @@ int h_burst_finished;
|
|||
int h_server_introduced;
|
||||
int h_server_eob;
|
||||
int h_client_exit;
|
||||
int h_after_client_exit;
|
||||
int h_umode_changed;
|
||||
int h_new_local_user;
|
||||
int h_new_remote_user;
|
||||
|
@ -86,6 +87,7 @@ init_hook(void)
|
|||
h_server_introduced = register_hook("server_introduced");
|
||||
h_server_eob = register_hook("server_eob");
|
||||
h_client_exit = register_hook("client_exit");
|
||||
h_after_client_exit = register_hook("after_client_exit");
|
||||
h_umode_changed = register_hook("umode_changed");
|
||||
h_new_local_user = register_hook("new_local_user");
|
||||
h_new_remote_user = register_hook("new_remote_user");
|
||||
|
|
Loading…
Reference in a new issue