Add support for CAP 3.2

This commit is contained in:
Patrick Griffis 2016-01-28 22:14:41 -05:00
parent 35d238ad3a
commit 981d55e84c
4 changed files with 35 additions and 6 deletions

View File

@ -572,6 +572,7 @@ typedef struct server
unsigned int sasl_mech; /* mechanism for sasl auth */
unsigned int sent_saslauth:1; /* have sent AUTHENICATE yet */
unsigned int sent_capend:1; /* have sent CAP END yet */
unsigned int waiting_on_cap:1; /* waiting on another line of CAP LS */
#ifdef USE_OPENSSL
unsigned int use_ssl:1; /* is server SSL capable? */
unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */

View File

@ -1735,12 +1735,23 @@ void
inbound_cap_ls (server *serv, char *nick, char *extensions_str,
const message_tags_data *tags_data)
{
char buffer[256]; /* buffer for requesting capabilities and emitting the signal */
char buffer[500]; /* buffer for requesting capabilities and emitting the signal */
gboolean want_cap = FALSE; /* format the CAP REQ string based on previous capabilities being requested or not */
gboolean want_sasl = FALSE; /* CAP END shouldn't be sent when SASL is requested, it needs further responses */
char **extensions;
int i;
if (g_str_has_prefix (extensions_str, "* "))
{
serv->waiting_on_cap = TRUE;
extensions_str += 2;
extensions_str += extensions_str[0] == ':' ? 1 : 0;
}
else
{
serv->waiting_on_cap = FALSE;
}
EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPLIST, serv->server_session, nick,
extensions_str, NULL, NULL, 0, tags_data->timestamp);
@ -1750,9 +1761,17 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str,
for (i=0; extensions[i]; i++)
{
const char *extension = extensions[i];
char *extension = extensions[i];
char *value;
gsize x;
/* CAP 3.2 can provide values */
if ((value = strchr (extension, '=')))
{
*value = '\0';
value++;
}
/* if the SASL password is set AND auth mode is set to SASL, request SASL auth */
if (!g_strcmp0 (extension, "sasl") &&
((serv->loginmethod == LOGIN_SASL && strlen (serv->password) != 0)
@ -1785,7 +1804,7 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str,
tags_data->timestamp);
tcp_sendf (serv, "%s\r\n", g_strchomp (buffer));
}
if (!want_sasl)
if (!want_sasl && !serv->waiting_on_cap)
{
/* if we use SASL, CAP END is dealt via raw numerics */
serv->sent_capend = TRUE;
@ -1796,14 +1815,22 @@ inbound_cap_ls (server *serv, char *nick, char *extensions_str,
void
inbound_cap_nak (server *serv, const message_tags_data *tags_data)
{
serv->sent_capend = TRUE;
tcp_send_len (serv, "CAP END\r\n", 9);
if (!serv->waiting_on_cap && !serv->sent_capend)
{
serv->sent_capend = TRUE;
tcp_send_len (serv, "CAP END\r\n", 9);
}
}
void
inbound_cap_list (server *serv, char *nick, char *extensions,
const message_tags_data *tags_data)
{
if (g_str_has_prefix (extensions, "* "))
{
extensions += 2;
extensions += extensions[0] == ':' ? 1 : 0;
}
EMIT_SIGNAL_TIMESTAMP (XP_TE_CAPACK, serv->server_session, nick, extensions,
NULL, NULL, 0, tags_data->timestamp);
}

View File

@ -48,7 +48,7 @@
static void
irc_login (server *serv, char *user, char *realname)
{
tcp_sendf (serv, "CAP LS\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */
tcp_sendf (serv, "CAP LS 302\r\n"); /* start with CAP LS as Charybdis sasl.txt suggests */
serv->sent_capend = FALSE; /* track if we have finished */
if (serv->password[0] && serv->loginmethod == LOGIN_PASS)

View File

@ -1732,6 +1732,7 @@ server_set_defaults (server *serv)
serv->nickcount = 1;
serv->end_of_motd = FALSE;
serv->sent_capend = FALSE;
serv->is_away = FALSE;
serv->supports_watch = FALSE;
serv->supports_monitor = FALSE;