1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-03 16:23:14 +02:00

Add SASL authentication in IRC plugin (task #8829), add function "string_encode_base64" in plugin API, fix bug with base64 encoding

New options for IRC servers:
- sasl_mechanism (only "plain" for now)
- sasl_username
- sasl_password
This commit is contained in:
Sebastien Helleu
2010-02-15 11:51:44 +01:00
parent 34272b7e4d
commit 341551f2f2
26 changed files with 925 additions and 115 deletions
+225 -1
View File
@@ -215,6 +215,158 @@ irc_protocol_replace_vars (struct t_irc_server *server,
return res;
}
/*
* irc_protocol_cmd_authenticate: 'authenticate' message received
*/
int
irc_protocol_cmd_authenticate (struct t_irc_server *server, const char *command,
int argc, char **argv, char **argv_eol)
{
const char *sasl_username, *sasl_password;
char *string, *string_base64;
int length_username, length;
/* AUTHENTICATE message looks like:
AUTHENTICATE +
*/
IRC_PROTOCOL_MIN_ARGS(2);
/* make C compiler happy */
(void) command;
(void) argv_eol;
if (strcmp (argv[1], "+") == 0)
{
sasl_username = IRC_SERVER_OPTION_STRING(server,
IRC_SERVER_OPTION_SASL_USERNAME);
sasl_password = IRC_SERVER_OPTION_STRING(server,
IRC_SERVER_OPTION_SASL_PASSWORD);
if (sasl_username && sasl_username[0]
&& sasl_password && sasl_password[0])
{
length_username = strlen (sasl_username);
length = ((length_username + 1) * 2) + strlen (sasl_password) + 1;
string = malloc (length);
if (string)
{
snprintf (string, length, "%s|%s|%s",
sasl_username, sasl_username, sasl_password);
string[length_username] = '\0';
string[(length_username * 2) + 1] = '\0';
string_base64 = malloc (length * 2);
if (string_base64)
{
weechat_string_encode_base64 (string, length - 1, string_base64);
irc_server_sendf (server, 0, "AUTHENTICATE %s", string_base64);
free (string_base64);
}
free (string);
}
}
}
return WEECHAT_RC_OK;
}
/*
* irc_protocol_cmd_cap: 'cap' message received (client capability)
*/
int
irc_protocol_cmd_cap (struct t_irc_server *server, const char *command,
int argc, char **argv, char **argv_eol)
{
char *ptr_caps, **items;
int num_items, sasl, i;
/* CAP message looks like:
:server CAP * LS :identify-msg multi-prefix sasl
:server CAP * ACK :sasl
*/
IRC_PROTOCOL_MIN_ARGS(4);
/* make C compiler happy */
(void) command;
if (strcmp (argv[3], "LS") == 0)
{
if (argc > 4)
{
ptr_caps = (argv_eol[4][0] == ':') ? argv_eol[4] + 1 : argv_eol[4];
weechat_printf (server->buffer,
_("%s%s: client capability, server supports: %s"),
weechat_prefix ("network"),
IRC_PLUGIN_NAME,
ptr_caps);
sasl = 0;
items = weechat_string_split (ptr_caps, " ", 0, 0, &num_items);
if (items)
{
for (i = 0; i < num_items; i++)
{
if (strcmp (items[i], "sasl") == 0)
{
sasl = 1;
break;
}
}
weechat_string_free_split (items);
}
if (sasl)
{
weechat_printf (server->buffer,
_("%s%s: client capability, requesting: sasl"),
weechat_prefix ("network"),
IRC_PLUGIN_NAME);
irc_server_sendf (server, 0, "CAP REQ :sasl");
}
else
{
weechat_printf (server->buffer,
_("%s%s: client capability: sasl not supported"),
weechat_prefix ("network"),
IRC_PLUGIN_NAME);
irc_server_sendf (server, 0, "CAP END");
}
}
}
else if (strcmp (argv[3], "ACK") == 0)
{
if (argc > 4)
{
ptr_caps = (argv_eol[4][0] == ':') ? argv_eol[4] + 1 : argv_eol[4];
weechat_printf (server->buffer,
_("%s%s: client capability, enabled: %s"),
weechat_prefix ("network"),
IRC_PLUGIN_NAME,
ptr_caps);
if (strcmp (ptr_caps, "sasl") == 0)
{
switch (IRC_SERVER_OPTION_INTEGER(server,
IRC_SERVER_OPTION_SASL_USERNAME))
{
case IRC_SASL_MECHANISM_PLAIN:
irc_server_sendf (server, 0, "AUTHENTICATE PLAIN");
break;
default:
irc_server_sendf (server, 0, "AUTHENTICATE PLAIN");
break;
}
if (server->hook_timer_sasl)
weechat_unhook (server->hook_timer_sasl);
server->hook_timer_sasl = weechat_hook_timer (5 * 1000, 0, 1,
&irc_server_timer_sasl_cb,
server);
}
}
}
return WEECHAT_RC_OK;
}
/*
* irc_protocol_cmd_error: error received from server
*/
@@ -3557,6 +3709,35 @@ irc_protocol_cmd_438 (struct t_irc_server *server, const char *command,
return WEECHAT_RC_OK;
}
/*
* irc_protocol_cmd_900: '900' command (logged in as (SASL))
*/
int
irc_protocol_cmd_900 (struct t_irc_server *server, const char *command,
int argc, char **argv, char **argv_eol)
{
/* 900 message looks like:
:server 900 mynick nick!user@host mynick :You are now logged in as mynick
*/
IRC_PROTOCOL_MIN_ARGS(6);
weechat_printf_tags (irc_msgbuffer_get_target_buffer (server, argv[3],
command, NULL,
NULL),
irc_protocol_tags (command, "irc_numeric"),
"%s%s %s(%s%s%s)",
weechat_prefix ("network"),
(argv_eol[5][0] == ':') ? argv_eol[5] + 1 : argv_eol[5],
IRC_COLOR_CHAT_DELIMITERS,
IRC_COLOR_CHAT_HOST,
argv[3],
IRC_COLOR_CHAT_DELIMITERS);
return WEECHAT_RC_OK;
}
/*
* irc_protocol_cmd_901: '901' command received (you are now logged in)
*/
@@ -3587,6 +3768,44 @@ irc_protocol_cmd_901 (struct t_irc_server *server, const char *command,
return WEECHAT_RC_OK;
}
/*
* irc_protocol_cmd_903: '903' command received (SASL authentication successful)
*/
int
irc_protocol_cmd_903 (struct t_irc_server *server, const char *command,
int argc, char **argv, char **argv_eol)
{
/* 903 message looks like:
:server 903 nick :SASL authentication successful
*/
irc_protocol_cmd_numeric (server, command, argc, argv, argv_eol);
irc_server_sendf (server, 0, "CAP END");
return WEECHAT_RC_OK;
}
/*
* irc_protocol_cmd_904: '904' command received (SASL authentication failed)
*/
int
irc_protocol_cmd_904 (struct t_irc_server *server, const char *command,
int argc, char **argv, char **argv_eol)
{
/* 904 message looks like:
:server 904 nick :SASL authentication failed
*/
irc_protocol_cmd_numeric (server, command, argc, argv, argv_eol);
irc_server_sendf (server, 0, "CAP END");
return WEECHAT_RC_OK;
}
/*
* irc_protocol_is_numeric_command: return 1 if given string is 100% numeric
*/
@@ -3621,7 +3840,9 @@ irc_protocol_recv_command (struct t_irc_server *server, const char *entire_line,
const char *cmd_name;
char **argv, **argv_eol;
struct t_irc_protocol_msg irc_protocol_messages[] =
{ { "error", /* error received from IRC server */ 1, &irc_protocol_cmd_error },
{ { "authenticate", /* authenticate */ 1, &irc_protocol_cmd_authenticate },
{ "cap", /* client capability */ 1, &irc_protocol_cmd_cap },
{ "error", /* error received from IRC server */ 1, &irc_protocol_cmd_error },
{ "invite", /* invite a nick on a channel */ 1, &irc_protocol_cmd_invite },
{ "join", /* join a channel */ 1, &irc_protocol_cmd_join },
{ "kick", /* forcibly remove a user from a channel */ 1, &irc_protocol_cmd_kick },
@@ -3741,7 +3962,10 @@ irc_protocol_recv_command (struct t_irc_server *server, const char *entire_line,
{ "501", /* unknown mode flag */ 1, &irc_protocol_cmd_error },
{ "502", /* can't change mode for other users */ 1, &irc_protocol_cmd_error },
{ "671", /* whois (secure connection) */ 1, &irc_protocol_cmd_whois_nick_msg },
{ "900", /* logged in as (SASL) */ 1, &irc_protocol_cmd_900 },
{ "901", /* you are now logged in */ 1, &irc_protocol_cmd_901 },
{ "903", /* SASL authentication successful */ 1, &irc_protocol_cmd_903 },
{ "904", /* SASL authentication failed */ 1, &irc_protocol_cmd_904 },
{ "973", /* whois (secure connection) */ 1, &irc_protocol_cmd_server_mode_reason },
{ "974", /* whois (secure connection) */ 1, &irc_protocol_cmd_server_mode_reason },
{ "975", /* whois (secure connection) */ 1, &irc_protocol_cmd_server_mode_reason },