Пример #1
0
void
trigger_callback_run_command (struct t_trigger *trigger,
                              struct t_gui_buffer *buffer,
                              struct t_hashtable *pointers,
                              struct t_hashtable *extra_vars,
                              int display_monitor)
{
    char *command_eval;
    int i;

    if (!trigger->commands)
        return;

    if (!buffer)
    {
        buffer = weechat_buffer_search_main ();
        if (!buffer)
            return;
    }

    for (i = 0; trigger->commands[i]; i++)
    {
        command_eval = weechat_string_eval_expression (trigger->commands[i],
                                                       pointers, extra_vars,
                                                       NULL);
        if (command_eval)
        {
            /* display debug info on trigger buffer */
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     _("%s  running command %s\"%s%s%s\"%s "
                                       "on buffer %s%s%s"),
                                     "\t",
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     command_eval,
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     weechat_color ("chat_buffer"),
                                     weechat_buffer_get_string (buffer,
                                                                "full_name"),
                                     weechat_color ("reset"));
            }
            weechat_command (buffer, command_eval);
            trigger->hook_count_cmd++;
        }
        free (command_eval);
    }
}
Пример #2
0
void
relay_weechat_alloc (struct t_relay_client *client)
{
    struct t_relay_weechat_data *weechat_data;
    char *password;

    password = weechat_string_eval_expression (weechat_config_string (relay_config_network_password),
               NULL, NULL, NULL);

    client->protocol_data = malloc (sizeof (*weechat_data));
    if (client->protocol_data)
    {
        RELAY_WEECHAT_DATA(client, password_ok) = (password && password[0]) ? 0 : 1;
        RELAY_WEECHAT_DATA(client, compression) = RELAY_WEECHAT_COMPRESSION_ZLIB;
        RELAY_WEECHAT_DATA(client, buffers_sync) =
            weechat_hashtable_new (32,
                                   WEECHAT_HASHTABLE_STRING,
                                   WEECHAT_HASHTABLE_INTEGER,
                                   NULL,
                                   NULL);
        RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL;
        RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist) = NULL;
        RELAY_WEECHAT_DATA(client, hook_signal_upgrade) = NULL;
        RELAY_WEECHAT_DATA(client, buffers_nicklist) =
            weechat_hashtable_new (32,
                                   WEECHAT_HASHTABLE_POINTER,
                                   WEECHAT_HASHTABLE_POINTER,
                                   NULL,
                                   NULL);
        weechat_hashtable_set_pointer (RELAY_WEECHAT_DATA(client, buffers_nicklist),
                                       "callback_free_value",
                                       &relay_weechat_free_buffers_nicklist);
        RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL;

        relay_weechat_hook_signals (client);
    }

    if (password)
        free (password);
}
Пример #3
0
int
trigger_callback_check_conditions (struct t_trigger *trigger,
                                   struct t_hashtable *pointers,
                                   struct t_hashtable *extra_vars)
{
    const char *conditions;
    char *value;
    int rc;

    conditions = weechat_config_string (trigger->options[TRIGGER_OPTION_CONDITIONS]);
    if (!conditions || !conditions[0])
        return 1;

    value = weechat_string_eval_expression (conditions,
                                            pointers,
                                            extra_vars,
                                            trigger_callback_hashtable_options);
    rc = (value && (strcmp (value, "1") == 0));
    if (value)
        free (value);

    return rc;
}
Пример #4
0
void
trigger_callback_replace_regex (struct t_trigger *trigger,
                                struct t_hashtable *pointers,
                                struct t_hashtable *extra_vars,
                                int display_monitor)
{
    char *value;
    const char *ptr_key, *ptr_value;
    int i, pointers_allocated;

    pointers_allocated = 0;

    if (trigger->regex_count == 0)
        return;

    if (!pointers)
    {
        pointers = weechat_hashtable_new (32,
                                          WEECHAT_HASHTABLE_STRING,
                                          WEECHAT_HASHTABLE_POINTER,
                                          NULL,
                                          NULL);
        if (!pointers)
            return;
        pointers_allocated = 1;
    }

    for (i = 0; i < trigger->regex_count; i++)
    {
        /* if regex is not set (invalid), skip it */
        if (!trigger->regex[i].regex)
            continue;

        ptr_key = (trigger->regex[i].variable) ?
            trigger->regex[i].variable :
            trigger_hook_regex_default_var[weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK])];
        if (!ptr_key || !ptr_key[0])
        {
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d: %s",
                                     i + 1, _("no variable"));
            }
            continue;
        }

        ptr_value = weechat_hashtable_get (extra_vars, ptr_key);
        if (!ptr_value)
        {
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d (%s): %s",
                                     i + 1, ptr_key, _("empty variable"));
            }
            continue;
        }

        weechat_hashtable_set (pointers, "regex", trigger->regex[i].regex);
        weechat_hashtable_set (trigger_callback_hashtable_options_regex,
                               "regex_replace",
                               trigger->regex[i].replace_escaped);

        value = weechat_string_eval_expression (
            ptr_value,
            pointers,
            extra_vars,
            trigger_callback_hashtable_options_regex);

        if (value)
        {
            /* display debug info on trigger buffer */
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d %s(%s%s%s)%s: "
                                     "%s\"%s%s%s\"",
                                     i + 1,
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     ptr_key,
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     weechat_color ("chat_delimiters"),
                                     weechat_color ("reset"),
                                     value,
                                     weechat_color ("chat_delimiters"));
            }
            weechat_hashtable_set (extra_vars, ptr_key, value);
            free (value);
        }
    }

    if (pointers_allocated)
        weechat_hashtable_free (pointers);
    else
        weechat_hashtable_remove (pointers, "regex");
}
Пример #5
0
void
trigger_callback_replace_regex (struct t_trigger *trigger,
                                struct t_hashtable *pointers,
                                struct t_hashtable *extra_vars,
                                int display_monitor)
{
    char *value, *replace_eval;
    const char *ptr_key, *ptr_value;
    int i;

    if (trigger->regex_count == 0)
        return;

    for (i = 0; i < trigger->regex_count; i++)
    {
        /* if regex is not set (invalid), skip it */
        if (!trigger->regex[i].regex)
            continue;

        ptr_key = (trigger->regex[i].variable) ?
            trigger->regex[i].variable :
            trigger_hook_regex_default_var[weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK])];
        if (!ptr_key || !ptr_key[0])
        {
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d: %s",
                                     i + 1, _("no variable"));
            }
            continue;
        }

        ptr_value = weechat_hashtable_get (extra_vars, ptr_key);
        if (!ptr_value)
        {
            if (trigger_buffer && display_monitor)
            {
                weechat_printf_tags (trigger_buffer, "no_trigger",
                                     "\t  regex %d (%s): %s",
                                     i + 1, ptr_key, _("empty variable"));
            }
            continue;
        }

        replace_eval = weechat_string_eval_expression (
            trigger->regex[i].replace_escaped,
            pointers,
            extra_vars,
            NULL);
        if (replace_eval)
        {
            value = weechat_string_replace_regex (ptr_value,
                                                  trigger->regex[i].regex,
                                                  replace_eval,
                                                  '$',
                                                  NULL, NULL);
            if (value)
            {
                /* display debug info on trigger buffer */
                if (trigger_buffer && display_monitor)
                {
                    weechat_printf_tags (trigger_buffer, "no_trigger",
                                         "\t  regex %d %s(%s%s%s)%s: "
                                         "%s\"%s%s%s\"",
                                         i + 1,
                                         weechat_color ("chat_delimiters"),
                                         weechat_color ("reset"),
                                         ptr_key,
                                         weechat_color ("chat_delimiters"),
                                         weechat_color ("reset"),
                                         weechat_color ("chat_delimiters"),
                                         weechat_color ("reset"),
                                         value,
                                         weechat_color ("chat_delimiters"));
                }
                weechat_hashtable_set (extra_vars, ptr_key, value);
                free (value);
            }
            free (replace_eval);
        }
    }
}
Пример #6
0
int
relay_server_sock_cb (const void *pointer, void *data, int fd)
{
    struct t_relay_server *server;
    struct sockaddr_in client_addr;
    struct sockaddr_in6 client_addr6;
    struct sockaddr_un client_addr_unix;

    socklen_t client_addr_size;
    void *ptr_addr;
    int client_fd, flags, set, max_clients, num_clients_on_port;
    char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
    char unix_address[sizeof (client_addr_unix.sun_path)];
    char *ptr_ip_address, *relay_password, *relay_totp_secret;

    /* make C compiler happy */
    (void) data;
    (void) fd;

    client_fd = -1;
    relay_password = NULL;
    relay_totp_secret = NULL;

    server = (struct t_relay_server *)pointer;

    if (server->ipv6)
    {
        ptr_addr = &client_addr6;
        client_addr_size = sizeof (struct sockaddr_in6);
    }
    else if (server->ipv4)
    {
        ptr_addr = &client_addr;
        client_addr_size = sizeof (struct sockaddr_in);
    }
    else
    {
        ptr_addr = &client_addr_unix;
        client_addr_size = sizeof (struct sockaddr_un);
    }

    memset (ptr_addr, 0, client_addr_size);

    client_fd = accept (server->sock, (struct sockaddr *)ptr_addr,
                        &client_addr_size);
    if (client_fd < 0)
    {
        if (server->unix_socket)
        {
            weechat_printf (NULL,
                            _("%s%s: cannot accept client on path %s (%s): "
                              "error %d %s"),
                            weechat_prefix ("error"), RELAY_PLUGIN_NAME,
                            server->path, server->protocol_string,
                            errno, strerror (errno));
        }
        else
        {
            weechat_printf (NULL,
                            _("%s%s: cannot accept client on port %d (%s): "
                              "error %d %s"),
                            weechat_prefix ("error"), RELAY_PLUGIN_NAME,
                            server->port, server->protocol_string,
                            errno, strerror (errno));
        }
        goto error;
    }

    /* check if relay password is empty and if it is not allowed */
    relay_password = weechat_string_eval_expression (
        weechat_config_string (relay_config_network_password),
        NULL, NULL, NULL);
    if (!weechat_config_boolean (relay_config_network_allow_empty_password)
        && (!relay_password || !relay_password[0]))
    {
        weechat_printf (NULL,
                        _("%s%s: cannot accept client because relay password "
                          "is empty, and option "
                          "relay.network.allow_empty_password is off"),
                        weechat_prefix ("error"), RELAY_PLUGIN_NAME);
        goto error;
    }

    if (server->protocol == RELAY_PROTOCOL_WEECHAT)
    {
        /*
         * TOTP can be enabled only as second factor, in addition to the
         * password (only for weechat protocol)
         */
        relay_totp_secret = weechat_string_eval_expression (
            weechat_config_string (relay_config_network_totp_secret),
            NULL, NULL, NULL);
        if ((!relay_password || !relay_password[0])
            && relay_totp_secret && relay_totp_secret[0])
        {
            weechat_printf (NULL,
                            _("%s%s: Time-based One-Time Password (TOTP) "
                              "can be enabled only as second factor, if the "
                              "password is not empty"),
                            weechat_prefix ("error"), RELAY_PLUGIN_NAME);
            goto error;
        }
        if (!relay_config_check_network_totp_secret (
                NULL, NULL, NULL,
                weechat_config_string (relay_config_network_totp_secret)))
        {
            goto error;
        }
    }

    /* check if we have reached the max number of clients on this port */
    max_clients = weechat_config_integer (relay_config_network_max_clients);
    if (max_clients > 0)
    {
        num_clients_on_port = relay_client_count_active_by_port (server->port);
        if (num_clients_on_port >= max_clients)
        {
            weechat_printf (
                NULL,
                NG_("%s%s: client not allowed (max %d client is "
                    "allowed at same time)",
                    "%s%s: client not allowed (max %d clients are "
                    "allowed at same time)",
                    max_clients),
                weechat_prefix ("error"), RELAY_PLUGIN_NAME,
                max_clients);
            goto error;
        }
    }

    /* get the IP address */
    ptr_ip_address = NULL;
    if (server->ipv6)
    {
        if (inet_ntop (AF_INET6,
                       &(client_addr6.sin6_addr),
                       ipv6_address,
                       INET6_ADDRSTRLEN))
        {
            ptr_ip_address = ipv6_address;

            if (strncmp (ptr_ip_address, "::ffff:", 7) == 0)
            {
                /* actually an IPv4-mapped IPv6 address, so skip "::ffff:" */
                ptr_ip_address += 7;
            }
        }
    }
    else if (server->ipv4)
    {
        if (inet_ntop (AF_INET,
                       &(client_addr.sin_addr),
                       ipv4_address,
                       INET_ADDRSTRLEN))
        {
            ptr_ip_address = ipv4_address;
        }
    }
    else
    {
        strncpy (unix_address, client_addr_unix.sun_path,
                 sizeof (unix_address));
        ptr_ip_address = unix_address;
    }

    /* check if IP is allowed, if not, just close socket */
    if (relay_config_regex_allowed_ips
        && (regexec (relay_config_regex_allowed_ips, ptr_ip_address, 0, NULL, 0) != 0))
    {
        if (weechat_relay_plugin->debug >= 1)
        {
            weechat_printf (NULL,
                            _("%s%s: IP address \"%s\" not allowed for relay"),
                            weechat_prefix ("error"),
                            RELAY_PLUGIN_NAME,
                            ptr_ip_address);
        }
        goto error;
    }

    /* set non-blocking mode for socket */
    flags = fcntl (client_fd, F_GETFL);
    if (flags == -1)
        flags = 0;
    fcntl (client_fd, F_SETFL, flags | O_NONBLOCK);

    /* set socket option SO_REUSEADDR */
    set = 1;
    if (setsockopt (client_fd, SOL_SOCKET, SO_REUSEADDR,
                    (void *) &set, sizeof (set)) < 0)
    {
        weechat_printf (NULL,
                        _("%s%s: cannot set socket option \"%s\" to %d: "
                          "error %d %s"),
                        weechat_prefix ("error"), RELAY_PLUGIN_NAME,
                        "SO_REUSEADDR", set, errno, strerror (errno));
        goto error;
    }

    /* add the client */
    relay_client_new (client_fd, ptr_ip_address, server);

    goto end;

error:
    if (client_fd >= 0)
        close (client_fd);

end:
    if (relay_password)
        free (relay_password);
    if (relay_totp_secret)
        free (relay_totp_secret);

    return WEECHAT_RC_OK;
}