Merge infrastructure for SASL authentication support from flashback.

This includes all of the underlying support, but doesn't hook it up to the
/SERVER command yet, so it's not useable at this point.


git-svn-id: svn://svn.code.sf.net/p/bitchx/code/trunk@216 13b04d17-f746-0410-82c6-800466cd88b0
This commit is contained in:
Kevin Easton
2012-12-30 02:22:56 +00:00
parent 0d67cac5f7
commit 1541299fa1
6 changed files with 177 additions and 1 deletions

View File

@@ -887,6 +887,75 @@ static void p_error(char *from, char **ArgList)
say("%s", ArgList[0]);
}
/*
* This only handles negotiating the SASL capability with the PLAIN method. It would
* be good to add DH-BLOWFISH, and later, full capability support.
*/
static void p_cap(char *from, char **ArgList)
{
char *caps, *p;
if (!strcmp(ArgList[1], "ACK"))
{
caps = LOCAL_COPY(ArgList[2]);
while ((p = next_arg(caps, &caps)) != NULL)
{
/* Only AUTHENTICATE before registration */
if (!strcmp(p, "sasl") && !is_server_connected(from_server))
{
my_send_to_server(from_server, "AUTHENTICATE PLAIN");
break;
}
}
}
else if (!strcmp(ArgList[1], "NAK"))
{
caps = LOCAL_COPY(ArgList[2]);
while ((p = next_arg(caps, &caps)) != NULL)
{
/* End capability negotiation to continue registration */
if (!strcmp(p, "sasl") && !is_server_connected(from_server))
{
my_send_to_server(from_server, "CAP END");
break;
}
}
}
}
static void p_authenticate(char *from, char **ArgList)
{
/* "AUTHENTICATE command MUST be used before registration is complete" */
if (is_server_connected(from_server))
return;
if (!strcmp(ArgList[0], "+"))
{
/* Message is BASE64(nick\0nick\0pass) */
char buf[IRCD_BUFFER_SIZE];
char *output = NULL;
char *nick = get_server_sasl_nick(from_server);
char *pass = get_server_sasl_pass(from_server);
size_t nick_len = nick ? strlen(nick) + 1 : 0; /* nick_len includes \0 */
size_t pass_len = pass ? strlen(pass) : 0;
/* "The client can abort an authentication by sending an asterisk as the data" */
if (!nick || !pass || nick_len * 2 + pass_len > sizeof buf)
{
my_send_to_server(from_server, "AUTHENTICATE *");
return;
}
memcpy(buf, nick, nick_len);
memcpy(buf + nick_len, nick, nick_len);
memcpy(buf + nick_len * 2, pass, pass_len);
output = base64_encode(buf, nick_len * 2 + pass_len);
my_send_to_server(from_server, "AUTHENTICATE %s", output);
new_free(&output);
}
}
void add_user_who (WhoEntry *w, char *from, char **ArgList)
{
char *userhost;
@@ -1758,7 +1827,9 @@ static void p_rpong (char *from, char **ArgList)
protocol_command rfc1459[] = {
{ "ADMIN", NULL, NULL, 0, 0, 0},
{ "AUTHENTICATE", p_authenticate, NULL, 0, 0, 0},
{ "AWAY", NULL, NULL, 0, 0, 0},
{ "CAP", p_cap, NULL, 0, 0, 0},
{ "CONNECT", NULL, NULL, 0, 0, 0},
{ "ERROR", p_error, NULL, 0, 0, 0},
{ "ERROR:", p_error, NULL, 0, 0, 0},