summaryrefslogtreecommitdiff
path: root/src/plugins/irc/irc-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/irc/irc-server.c')
-rw-r--r--src/plugins/irc/irc-server.c154
1 files changed, 144 insertions, 10 deletions
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index 0c1b8da7d..e59fc5c3b 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -58,19 +58,26 @@ struct t_irc_message *irc_recv_msgq = NULL;
struct t_irc_message *irc_msgq_last_msg = NULL;
char *irc_server_option_string[IRC_SERVER_NUM_OPTIONS] =
-{ "addresses", "proxy", "ipv6", "ssl", "ssl_cert", "ssl_dhkey_size",
- "ssl_verify", "password", "autoconnect", "autoreconnect",
- "autoreconnect_delay", "nicks", "username", "realname", "local_hostname",
+{ "addresses", "proxy", "ipv6",
+ "ssl", "ssl_cert", "ssl_dhkey_size", "ssl_verify",
+ "password", "sasl_mechanism", "sasl_username", "sasl_password",
+ "autoconnect", "autoreconnect", "autoreconnect_delay",
+ "nicks", "username", "realname", "local_hostname",
"command", "command_delay", "autojoin", "autorejoin", "autorejoin_delay",
};
char *irc_server_option_default[IRC_SERVER_NUM_OPTIONS] =
-{ "", "", "off", "off", "", "2048",
- "on", "", "off", "on",
- "30", "", "", "", "",
+{ "", "", "off",
+ "off", "", "2048", "on",
+ "", "plain", "", "",
+ "off", "on", "30",
+ "", "", "", "",
"", "0", "", "off", "30",
};
+char *irc_sasl_mechanism_string[IRC_NUM_SASL_MECHANISMS] =
+{ "plain", /*"dh-blowfish"*/ };
+
void irc_server_reconnect (struct t_irc_server *server);
void irc_server_check_away ();
@@ -129,6 +136,26 @@ irc_server_search_option (const char *option_name)
}
/*
+ * irc_server_sasl_enabled: return 1 if SASL is enabled on server
+ * 0 if SASL is NOT enabled on server
+ */
+
+int
+irc_server_sasl_enabled (struct t_irc_server *server)
+{
+ const char *sasl_username, *sasl_password;
+
+ sasl_username = IRC_SERVER_OPTION_STRING(server,
+ IRC_SERVER_OPTION_SASL_USERNAME);
+ sasl_password = IRC_SERVER_OPTION_STRING(server,
+ IRC_SERVER_OPTION_SASL_PASSWORD);
+
+ /* SASL is enabled if username AND password are set */
+ return (sasl_username && sasl_username[0]
+ && sasl_password && sasl_password[0]) ? 1 : 0;
+}
+
+/*
* irc_server_get_name_without_port: get name of server without port
* (ends before first '/' if found)
*/
@@ -295,6 +322,7 @@ irc_server_alloc (const char *name)
new_server->sock = -1;
new_server->hook_connect = NULL;
new_server->hook_fd = NULL;
+ new_server->hook_timer_sasl = NULL;
new_server->is_connected = 0;
new_server->ssl_connected = 0;
new_server->unterminated_message = NULL;
@@ -684,10 +712,16 @@ irc_server_free_data (struct t_irc_server *server)
free (server->ports_array);
if (server->current_ip)
free (server->current_ip);
- if (server->nicks_array)
- weechat_string_free_split (server->nicks_array);
+ if (server->hook_connect)
+ weechat_unhook (server->hook_connect);
+ if (server->hook_fd)
+ weechat_unhook (server->hook_fd);
+ if (server->hook_timer_sasl)
+ weechat_unhook (server->hook_timer_sasl);
if (server->unterminated_message)
free (server->unterminated_message);
+ if (server->nicks_array)
+ weechat_string_free_split (server->nicks_array);
if (server->nick)
free (server->nick);
if (server->nick_modes)
@@ -696,6 +730,11 @@ irc_server_free_data (struct t_irc_server *server)
free (server->prefix);
if (server->away_message)
free (server->away_message);
+ if (server->cmd_list_regexp)
+ {
+ regfree (server->cmd_list_regexp);
+ free (server->cmd_list_regexp);
+ }
for (i = 0; i < IRC_SERVER_NUM_OUTQUEUES_PRIO; i++)
{
irc_server_outqueue_free_all (server, i);
@@ -1694,6 +1733,41 @@ irc_server_recv_cb (void *arg_server, int fd)
}
/*
+ * irc_server_timer_sasl_cb: callback for SASL authentication timer
+ * it is called if there is a timeout with SASL
+ * authentication
+ * (if SASL authentication is ok or failed, then
+ * hook timer is removed before this callback is
+ * called)
+ */
+
+int
+irc_server_timer_sasl_cb (void *arg_server, int remaining_calls)
+{
+ struct t_irc_server *server;
+
+ /* make C compiler happy */
+ (void) remaining_calls;
+
+ server = (struct t_irc_server *)arg_server;
+
+ if (!server)
+ return WEECHAT_RC_ERROR;
+
+ server->hook_timer_sasl = NULL;
+
+ if (!server->is_connected)
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: sasl authentication timeout"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME);
+ irc_server_sendf (server, 0, "CAP END");
+ }
+
+ return WEECHAT_RC_OK;
+}
+
+/*
* irc_server_timer_cb: timer called each second to perform some operations
* on servers
*/
@@ -1795,6 +1869,12 @@ void
irc_server_close_connection (struct t_irc_server *server)
{
int i;
+
+ if (server->hook_timer_sasl)
+ {
+ weechat_unhook (server->hook_timer_sasl);
+ server->hook_timer_sasl = NULL;
+ }
if (server->hook_fd)
{
@@ -1883,7 +1963,7 @@ void
irc_server_login (struct t_irc_server *server)
{
const char *password, *username, *realname;
-
+
password = IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_PASSWORD);
username = IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_USERNAME);
realname = IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_REALNAME);
@@ -1898,6 +1978,11 @@ irc_server_login (struct t_irc_server *server)
server->nicks_array[0] : "weechat");
}
+ if (irc_server_sasl_enabled (server))
+ {
+ irc_server_sendf (server, 0, "CAP LS");
+ }
+
irc_server_sendf (server, 0,
"NICK %s\n"
"USER %s %s %s :%s",
@@ -3276,6 +3361,15 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
if (!weechat_infolist_new_var_string (ptr_item, "password",
IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_PASSWORD)))
return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "sasl_mechanism",
+ IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_SASL_MECHANISM)))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "sasl_username",
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_USERNAME)))
+ return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "sasl_password",
+ IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_SASL_PASSWORD)))
+ return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "autoconnect",
IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_AUTOCONNECT)))
return 0;
@@ -3374,19 +3468,21 @@ irc_server_print_log ()
{
weechat_log_printf ("");
weechat_log_printf ("[server %s (addr:0x%lx)]", ptr_server->name, ptr_server);
-
+ /* addresses */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_ADDRESSES]))
weechat_log_printf (" addresses. . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_ADDRESSES));
else
weechat_log_printf (" addresses. . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_ADDRESSES]));
+ /* proxy */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_PROXY]))
weechat_log_printf (" proxy. . . . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_PROXY));
else
weechat_log_printf (" proxy. . . . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_PROXY]));
+ /* ipv6 */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_IPV6]))
weechat_log_printf (" ipv6 . . . . . . . . : null (%s)",
(IRC_SERVER_OPTION_BOOLEAN(ptr_server, IRC_SERVER_OPTION_IPV6)) ?
@@ -3395,6 +3491,7 @@ irc_server_print_log ()
weechat_log_printf (" ipv6 . . . . . . . . : %s",
weechat_config_boolean (ptr_server->options[IRC_SERVER_OPTION_IPV6]) ?
"on" : "off");
+ /* ssl */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SSL]))
weechat_log_printf (" ssl. . . . . . . . . : null (%s)",
(IRC_SERVER_OPTION_BOOLEAN(ptr_server, IRC_SERVER_OPTION_SSL)) ?
@@ -3403,18 +3500,21 @@ irc_server_print_log ()
weechat_log_printf (" ssl. . . . . . . . . : %s",
weechat_config_boolean (ptr_server->options[IRC_SERVER_OPTION_SSL]) ?
"on" : "off");
+ /* ssl_cert */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SSL_CERT]))
weechat_log_printf (" ssl_cert . . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_SSL_CERT));
else
weechat_log_printf (" ssl_cert . . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_SSL_CERT]));
+ /* ssl_dhkey_size */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SSL_DHKEY_SIZE]))
weechat_log_printf (" ssl_dhkey_size . . . : null ('%d')",
IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_SSL_DHKEY_SIZE));
else
weechat_log_printf (" ssl_dhkey_size . . . : '%d'",
weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_SSL_DHKEY_SIZE]));
+ /* ssl_verify */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SSL_VERIFY]))
weechat_log_printf (" ssl_verify . . . . . : null (%s)",
(IRC_SERVER_OPTION_BOOLEAN(ptr_server, IRC_SERVER_OPTION_SSL_VERIFY)) ?
@@ -3423,10 +3523,31 @@ irc_server_print_log ()
weechat_log_printf (" ssl_verify . . . . . : %s",
weechat_config_boolean (ptr_server->options[IRC_SERVER_OPTION_SSL_VERIFY]) ?
"on" : "off");
+ /* password */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_PASSWORD]))
weechat_log_printf (" password . . . . . . : null");
else
weechat_log_printf (" password . . . . . . : (hidden)");
+ /* sasl_mechanism */
+ if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SASL_MECHANISM]))
+ weechat_log_printf (" sasl_mechanism . . . : null ('%s')",
+ irc_sasl_mechanism_string[IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_SASL_MECHANISM)]);
+ else
+ weechat_log_printf (" sasl_mechanism . . . : '%s'",
+ irc_sasl_mechanism_string[weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_SASL_MECHANISM])]);
+ /* sasl_username */
+ if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SASL_USERNAME]))
+ weechat_log_printf (" sasl_username. . . . : null ('%s')",
+ IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_SASL_USERNAME));
+ else
+ weechat_log_printf (" sasl_username. . . . : '%s'",
+ weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_USERNAME]));
+ /* sasl_password */
+ if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_SASL_PASSWORD]))
+ weechat_log_printf (" sasl_password. . . . : null");
+ else
+ weechat_log_printf (" sasl_password. . . . : (hidden)");
+ /* autoconnect */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AUTOCONNECT]))
weechat_log_printf (" autoconnect. . . . . : null (%s)",
(IRC_SERVER_OPTION_BOOLEAN(ptr_server, IRC_SERVER_OPTION_AUTOCONNECT)) ?
@@ -3435,6 +3556,7 @@ irc_server_print_log ()
weechat_log_printf (" autoconnect. . . . . : %s",
weechat_config_boolean (ptr_server->options[IRC_SERVER_OPTION_AUTOCONNECT]) ?
"on" : "off");
+ /* autoreconnect */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AUTORECONNECT]))
weechat_log_printf (" autoreconnect. . . . : null (%s)",
(IRC_SERVER_OPTION_BOOLEAN(ptr_server, IRC_SERVER_OPTION_AUTORECONNECT)) ?
@@ -3443,52 +3565,61 @@ irc_server_print_log ()
weechat_log_printf (" autoreconnect. . . . : %s",
weechat_config_boolean (ptr_server->options[IRC_SERVER_OPTION_AUTORECONNECT]) ?
"on" : "off");
+ /* autoreconnect_delay */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AUTORECONNECT_DELAY]))
weechat_log_printf (" autoreconnect_delay. : null (%d)",
IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_AUTORECONNECT_DELAY));
else
weechat_log_printf (" autoreconnect_delay. : %d",
weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_AUTORECONNECT_DELAY]));
+ /* nicks */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_NICKS]))
weechat_log_printf (" nicks. . . . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_NICKS));
else
weechat_log_printf (" nicks. . . . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_NICKS]));
+ /* username */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_USERNAME]))
weechat_log_printf (" username . . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_USERNAME));
else
weechat_log_printf (" username . . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_USERNAME]));
+ /* realname */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_REALNAME]))
weechat_log_printf (" realname . . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_REALNAME));
else
weechat_log_printf (" realname . . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_REALNAME]));
+ /* local_hostname */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_LOCAL_HOSTNAME]))
weechat_log_printf (" local_hostname . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_LOCAL_HOSTNAME));
else
weechat_log_printf (" local_hostname . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_LOCAL_HOSTNAME]));
+ /* command */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_COMMAND]))
weechat_log_printf (" command. . . . . . . : null");
else
weechat_log_printf (" command. . . . . . . : (hidden)");
+ /* command_delay */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_COMMAND_DELAY]))
weechat_log_printf (" command_delay. . . . : null (%d)",
IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_COMMAND_DELAY));
else
weechat_log_printf (" command_delay. . . . : %d",
weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_COMMAND_DELAY]));
+ /* autojoin */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AUTOJOIN]))
weechat_log_printf (" autojoin . . . . . . : null ('%s')",
IRC_SERVER_OPTION_STRING(ptr_server, IRC_SERVER_OPTION_AUTOJOIN));
else
weechat_log_printf (" autojoin . . . . . . : '%s'",
weechat_config_string (ptr_server->options[IRC_SERVER_OPTION_AUTOJOIN]));
+ /* autorejoin */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AUTOREJOIN]))
weechat_log_printf (" autorejoin . . . . . : null (%s)",
(IRC_SERVER_OPTION_BOOLEAN(ptr_server, IRC_SERVER_OPTION_AUTOREJOIN)) ?
@@ -3497,12 +3628,14 @@ irc_server_print_log ()
weechat_log_printf (" autorejoin . . . . . : %s",
weechat_config_boolean (ptr_server->options[IRC_SERVER_OPTION_AUTOREJOIN]) ?
"on" : "off");
+ /* autorejoin_delay */
if (weechat_config_option_is_null (ptr_server->options[IRC_SERVER_OPTION_AUTOREJOIN_DELAY]))
weechat_log_printf (" autorejoin_delay . . : null (%d)",
IRC_SERVER_OPTION_INTEGER(ptr_server, IRC_SERVER_OPTION_AUTOREJOIN_DELAY));
else
weechat_log_printf (" autorejoin_delay . . : %d",
weechat_config_integer (ptr_server->options[IRC_SERVER_OPTION_AUTOREJOIN_DELAY]));
+ /* other server variables */
weechat_log_printf (" temp_server. . . . . : %d", ptr_server->temp_server);
weechat_log_printf (" reloading_from_config: %d", ptr_server->reloaded_from_config);
weechat_log_printf (" reloaded_from_config : %d", ptr_server->reloaded_from_config);
@@ -3514,6 +3647,7 @@ irc_server_print_log ()
weechat_log_printf (" sock . . . . . . . . : %d", ptr_server->sock);
weechat_log_printf (" hook_connect . . . . : 0x%lx", ptr_server->hook_connect);
weechat_log_printf (" hook_fd. . . . . . . : 0x%lx", ptr_server->hook_fd);
+ weechat_log_printf (" hook_timer_sasl. . . : 0x%lx", ptr_server->hook_timer_sasl);
weechat_log_printf (" is_connected . . . . : %d", ptr_server->is_connected);
weechat_log_printf (" ssl_connected. . . . : %d", ptr_server->ssl_connected);
#ifdef HAVE_GNUTLS