m_sasl: Don't process authentication messages if SASL has been aborted, but track failures
This commit is contained in:
parent
958c354cca
commit
40a766a0a0
1 changed files with 23 additions and 9 deletions
|
@ -235,6 +235,7 @@ me_sasl(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
int parc, const char *parv[])
|
int parc, const char *parv[])
|
||||||
{
|
{
|
||||||
struct Client *target_p, *agent_p;
|
struct Client *target_p, *agent_p;
|
||||||
|
bool in_progress;
|
||||||
|
|
||||||
/* Let propagate if not addressed to us, or if broadcast.
|
/* Let propagate if not addressed to us, or if broadcast.
|
||||||
* Only SASL agents can answer global requests.
|
* Only SASL agents can answer global requests.
|
||||||
|
@ -257,22 +258,29 @@ me_sasl(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
if(!IsService(agent_p))
|
if(!IsService(agent_p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* If SASL has been aborted, we only want to track authentication failures. */
|
||||||
|
in_progress = target_p->localClient->sasl_out != 0;
|
||||||
|
|
||||||
/* Reject if someone has already answered. */
|
/* Reject if someone has already answered. */
|
||||||
if(*target_p->localClient->sasl_agent && strncmp(parv[1], target_p->localClient->sasl_agent, IDLEN))
|
if(*target_p->localClient->sasl_agent && strncmp(parv[1], target_p->localClient->sasl_agent, IDLEN))
|
||||||
return;
|
return;
|
||||||
else if(!*target_p->localClient->sasl_agent)
|
else if(!*target_p->localClient->sasl_agent && in_progress)
|
||||||
rb_strlcpy(target_p->localClient->sasl_agent, parv[1], IDLEN);
|
rb_strlcpy(target_p->localClient->sasl_agent, parv[1], IDLEN);
|
||||||
|
|
||||||
if(*parv[3] == 'C')
|
if(*parv[3] == 'C')
|
||||||
{
|
{
|
||||||
|
if (in_progress) {
|
||||||
sendto_one(target_p, "AUTHENTICATE %s", parv[4]);
|
sendto_one(target_p, "AUTHENTICATE %s", parv[4]);
|
||||||
target_p->localClient->sasl_messages++;
|
target_p->localClient->sasl_messages++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(*parv[3] == 'D')
|
else if(*parv[3] == 'D')
|
||||||
{
|
{
|
||||||
if(*parv[4] == 'F')
|
if(*parv[4] == 'F')
|
||||||
{
|
{
|
||||||
|
if (in_progress) {
|
||||||
sendto_one(target_p, form_str(ERR_SASLFAIL), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
|
sendto_one(target_p, form_str(ERR_SASLFAIL), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
|
||||||
|
}
|
||||||
/* Failures with zero messages are just "unknown mechanism" errors; don't count those. */
|
/* Failures with zero messages are just "unknown mechanism" errors; don't count those. */
|
||||||
if(target_p->localClient->sasl_messages > 0)
|
if(target_p->localClient->sasl_messages > 0)
|
||||||
{
|
{
|
||||||
|
@ -294,17 +302,23 @@ me_sasl(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
}
|
}
|
||||||
else if(*parv[4] == 'S')
|
else if(*parv[4] == 'S')
|
||||||
{
|
{
|
||||||
|
if (in_progress) {
|
||||||
sendto_one(target_p, form_str(RPL_SASLSUCCESS), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
|
sendto_one(target_p, form_str(RPL_SASLSUCCESS), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
|
||||||
target_p->localClient->sasl_failures = 0;
|
target_p->localClient->sasl_failures = 0;
|
||||||
target_p->localClient->sasl_complete = 1;
|
target_p->localClient->sasl_complete = 1;
|
||||||
ServerStats.is_ssuc++;
|
ServerStats.is_ssuc++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*target_p->localClient->sasl_agent = '\0'; /* Blank the stored agent so someone else can answer */
|
*target_p->localClient->sasl_agent = '\0'; /* Blank the stored agent so someone else can answer */
|
||||||
target_p->localClient->sasl_messages = 0;
|
target_p->localClient->sasl_messages = 0;
|
||||||
}
|
}
|
||||||
else if(*parv[3] == 'M')
|
else if(*parv[3] == 'M')
|
||||||
|
{
|
||||||
|
if (in_progress) {
|
||||||
sendto_one(target_p, form_str(RPL_SASLMECHS), me.name, EmptyString(target_p->name) ? "*" : target_p->name, parv[4]);
|
sendto_one(target_p, form_str(RPL_SASLMECHS), me.name, EmptyString(target_p->name) ? "*" : target_p->name, parv[4]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
me_mechlist(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
me_mechlist(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue