api: use hashtable "options" for command arguments in function hook_process_hashtable (optional, default is a split of string with command)

v2.8-utf8proc
Sebastien Helleu 2012-11-22 19:55:38 +01:00
parent 425256b38d
commit 1281b18688
5 changed files with 266 additions and 23 deletions

View File

@ -1,14 +1,12 @@
WeeChat ChangeLog
=================
Sébastien Helleu <flashcode@flashtux.org>
v0.4.0-dev, 2012-11-18
v0.4.0-dev, 2012-11-22
Version 0.4.0 (under dev!)
--------------------------
* core: do not call shell to execute command in hook_process (fix security
problem when a plugin/script gives untrusted command) (bug #37764)
* core: stop cmake if gcrypt lib is not found (bug #37671)
* core: add incomplete mouse events "event-down" and "event-drag" (task #11840)
* core: add command /eval, use expression in conditions for bars
@ -20,6 +18,10 @@ Version 0.4.0 (under dev!)
(problem with nick displayed in first line of screen) (bug #37556)
* core: fix wrapping of words with wide chars (the break was made before the
correct position)
* api: use hashtable "options" for command arguments in function
hook_process_hashtable (optional, default is a split of string with command)
* api: do not call shell to execute command in hook_process (fix security
problem when a plugin/script gives untrusted command) (bug #37764)
* api: add new function "string_eval_expression"
* api: connect with IPv6 by default in hook_connect (with fallback to IPv4),
shuffle list of hosts for a same address, add argument "retry" for

View File

@ -6918,6 +6918,15 @@ weechat_hook_process
Hook a process (launched with fork), and catch output.
[NOTE]
Since version 0.3.9.2, the shell is not used any more to execute the command.
WeeChat makes an automatic split of the command and its arguments (like the
shell does). +
If the split is not correct (according to quotes in your command), or if you
want to use shell, you can use function
<<_weechat_hook_process_hashtable,weechat_hook_process_hashtable>> with
arguments in the hashtable 'options' (_new in version 0.4.0_).
Prototype:
[source,C]
@ -7066,8 +7075,13 @@ struct t_hook *weechat_hook_process_hashtable (const char *command,
Arguments are the same as function <<_weechat_hook_process,weechat_hook_process>>,
with an extra argument:
* 'options': options for command executed (see table below); the hashtable is
duplicated in function, so it's safe to free it after this call
* 'options': options for command executed; the hashtable is duplicated in
function, so it's safe to free it after this call
For a standard command (not beginning with "url:"), the hashtable 'options' can
contain arguments for command (and then 'command' must be only the command
without arguments) (_new in version 0.4.0_). +
The keys in hashtable must be: 'arg1', 'arg2', ...
For command "url:...", following options are available (see
`man curl_easy_setopt` for a description of each option):
@ -7120,6 +7134,7 @@ my_process_cb (void *data, const char *command, int return_code,
return WEECHAT_RC_OK;
}
/* example 1: download URL */
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
@ -7134,6 +7149,42 @@ if (options)
&my_process_cb, NULL);
weechat_hashtable_free (options);
}
/* example 2: execute a notify program with a message from someone */
struct t_hashtable *options_cmd1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options_cmd1)
{
weechat_hashtable_set (options_cmd1, "arg1", "-from");
weechat_hashtable_set (options_cmd1, "arg2", nick);
weechat_hashtable_set (options_cmd1, "arg3", "-msg");
weechat_hashtable_set (options_cmd1, "arg4", message); /* untrusted argument */
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("my-notify-command",
options_cmd1,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options_cmd1);
}
/* example 3: call shell to execute a command (command must be SAFE) */
struct t_hashtable *options_cmd2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options_cmd2)
{
weechat_hashtable_set (options_cmd2, "arg1", "-c");
weechat_hashtable_set (options_cmd2, "arg2", "ls -l /tmp | grep something");
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("sh",
options_cmd2,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options_cmd2);
}
----------------------------------------
Script (Python):
@ -7156,9 +7207,24 @@ def my_process_cb(data, command, return_code, out, err):
weechat.prnt("", "stderr: %s" % err)
return weechat.WEECHAT_RC_OK
hook = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
# example 1: download URL
hook1 = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
# example 2: execute a notify program with a message from someone
hook2 = weechat.hook_process_hashtable("my-notify-command",
{ "arg1": "-from",
"arg2": nick,
"arg3": "-msg",
"arg4": message }, # untrusted argument
20000, "my_process_cb", "")
# example 3: call shell to execute a command (command must be SAFE)
hook3 = weechat.hook_process_hashtable("sh",
{ "arg1": "-c",
"arg2": "ls -l /tmp | grep something" },
20000, "my_process_cb", "")
----------------------------------------
weechat_hook_connect

View File

@ -7014,6 +7014,15 @@ weechat_hook_process
Accroche un processus (lancé par un fork), et intercepter sa sortie.
[NOTE]
Depuis la version 0.3.9.2, le shell n'est plus utilisé pour exécuter la
commande. WeeChat effectue un découpage automatique de la commande et de ses
paramètres (comme le fait le shell). +
Si le découpage n'est pas correct (selon les guillemets utilisés dans votre
commande), ou si vous souhaitez utiliser le shell, vous pouvez utiliser la
fonction <<_weechat_hook_process_hashtable,weechat_hook_process_hashtable>> avec
les paramètres dans la hashtable 'options' (_nouveau dans la version 0.4.0_).
Prototype :
[source,C]
@ -7169,9 +7178,14 @@ Les paramètres sont les mêmes que ceux de la fonction
<<_weechat_hook_process,weechat_hook_process>>, avec un paramètre
supplémentaire :
* 'options' : options pour la commande exécutée (voir le tableau ci-dessous);
la hashtable est dupliquée dans la fonction, donc il est possible de la
supprimer après cet appel
* 'options' : options pour la commande exécutée; la hashtable est dupliquée dans
la fonction, donc il est possible de la supprimer après cet appel
Pour une commande standard (ne commençant pas par "url:"), la hashtable
'options' peut contenir les paramètres pour la commande (et donc 'command' doit
être seulement la commande sans les paramètres)
(_nouveau dans la version 0.4.0_). +
Les clés dans la hashtable doivent être: 'arg1', 'arg2', ...
Pour la commande "url:...", les options suivantes sont disponibles (voir
`man curl_easy_setopt` pour une description de chaque option) :
@ -7226,6 +7240,7 @@ my_process_cb (void *data, const char *command, int return_code,
return WEECHAT_RC_OK;
}
/* exemple 1: téléchargement d'une URL */
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
@ -7240,6 +7255,42 @@ if (options)
&my_process_cb, NULL);
weechat_hashtable_free (options);
}
/* exemple 2: exécution d'un programme de notification avec le message de quelqu'un */
struct t_hashtable *options_cmd1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options_cmd1)
{
weechat_hashtable_set (options_cmd1, "arg1", "-from");
weechat_hashtable_set (options_cmd1, "arg2", nick);
weechat_hashtable_set (options_cmd1, "arg3", "-msg");
weechat_hashtable_set (options_cmd1, "arg4", message); /* paramètre non sûr */
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("my-notify-command",
options_cmd1,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options_cmd1);
}
/* exemple 3: appeler le shell pour exécuter la commande (la commande doit être SURE) */
struct t_hashtable *options_cmd2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options_cmd2)
{
weechat_hashtable_set (options_cmd2, "arg1", "-c");
weechat_hashtable_set (options_cmd2, "arg2", "ls -l /tmp | grep something");
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("sh",
options_cmd2,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options_cmd2);
}
----------------------------------------
Script (Python):
@ -7262,9 +7313,24 @@ def my_process_cb(data, command, return_code, out, err):
weechat.prnt("", "stderr: %s" % err)
return weechat.WEECHAT_RC_OK
hook = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
# exemple 1: téléchargement d'une URL
hook1 = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
# exemple 2: exécution d'un programme de notification avec le message de quelqu'un
hook2 = weechat.hook_process_hashtable("my-notify-command",
{ "arg1": "-from",
"arg2": nick,
"arg3": "-msg",
"arg4": message }, # paramètre non sûr
20000, "my_process_cb", "")
# exemple 3: appeler le shell pour exécuter la commande (la commande doit être SURE)
hook3 = weechat.hook_process_hashtable("sh",
{ "arg1": "-c",
"arg2": "ls -l /tmp | grep something" },
20000, "my_process_cb", "")
----------------------------------------
weechat_hook_connect

View File

@ -6946,6 +6946,15 @@ weechat_hook_process
Hook su un processo (lanciato con un fork), e cattura l'output.
[NOTE]
// TRANSLATION MISSING
Since version 0.3.9.2, the shell is not used any more to execute the command.
WeeChat makes an automatic split of command and arguments (like the shell does).
If the split is not correct (according to quotes in your command), or if you
want to use shell, you can use function
<<_weechat_hook_process_hashtable,weechat_hook_process_hashtable>> with
arguments in the hashtable 'options' (_new in version 0.4.0_).
Prototipo:
[source,C]
@ -7098,9 +7107,14 @@ struct t_hook *weechat_hook_process_hashtable (const char *command,
Gli argomenti sono gli stessi della funzione
<<_weechat_hook_process,weechat_hook_process>>, con un argomento aggiuntivo:
* 'options': le opzioni per il comando eseguito (consultare la tabella in
basso); la tabella hash è duplicata nella funzione, per cui è possibile
liberarla dopo questa chiamata
* 'options': le opzioni per il comando eseguito; la tabella hash è duplicata
nella funzione, per cui è possibile liberarla dopo questa chiamata
// TRANSLATION MISSING
For a standard command (not beginning with "url:"), the hashtable 'options' can
contain arguments for command (and then 'command' must be only the command
without arguments) (_new in version 0.4.0_). +
The keys in hashtable must be: 'arg1', 'arg2', ...
Per il comando "url:..." sono disponibili le seguenti opzioni (consultare
`man curl_easy_setopt` per la descrizione di ogni opzione):
@ -7155,6 +7169,7 @@ my_process_cb (void *data, const char *command, int return_code,
return WEECHAT_RC_OK;
}
/* example 1: download URL */
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
@ -7169,6 +7184,42 @@ if (options)
&my_process_cb, NULL);
weechat_hashtable_free (options);
}
/* example 2: execute a notify program with a message from someone */
struct t_hashtable *options_cmd1 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options_cmd1)
{
weechat_hashtable_set (options_cmd1, "arg1", "-from");
weechat_hashtable_set (options_cmd1, "arg2", nick);
weechat_hashtable_set (options_cmd1, "arg3", "-msg");
weechat_hashtable_set (options_cmd1, "arg4", message); /* unsafe argument */
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("my-notify-command",
options_cmd1,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options_cmd1);
}
/* example 3: call shell to execute a command (command must be SAFE) */
struct t_hashtable *options_cmd2 = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (options_cmd2)
{
weechat_hashtable_set (options_cmd2, "arg1", "-c");
weechat_hashtable_set (options_cmd2, "arg2", "ls -l /tmp | grep something");
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("sh",
options_cmd2,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options_cmd2);
}
----------------------------------------
Script (Python):
@ -7191,9 +7242,24 @@ def my_process_cb(data, command, return_code, out, err):
weechat.prnt("", "stderr: %s" % err)
return weechat.WEECHAT_RC_OK
hook = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
# example 1: download URL
hook1 = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
# example 2: execute a notify program with a message from someone
hook2 = weechat.hook_process_hashtable("my-notify-command",
{ "arg1": "-from",
"arg2": nick,
"arg3": "-msg",
"arg4": message }, # unsafe argument
20000, "my_process_cb", "")
# example 3: call shell to execute a command (command must be SAFE)
hook3 = weechat.hook_process_hashtable("sh",
{ "arg1": "-c",
"arg2": "ls -l /tmp | grep something" },
20000, "my_process_cb", "")
----------------------------------------
weechat_hook_connect

View File

@ -1388,9 +1388,9 @@ hook_process (struct t_weechat_plugin *plugin,
void
hook_process_child (struct t_hook *hook_process)
{
char **exec_args;
char **exec_args, str_arg[64];
const char *ptr_url;
int rc, i;
int rc, i, num_args;
/*
* close stdin, so that process will fail to read stdin (process reading
@ -1429,7 +1429,50 @@ hook_process_child (struct t_hook *hook_process)
else
{
/* launch command */
exec_args = string_split_shell (HOOK_PROCESS(hook_process, command));
num_args = 0;
if (HOOK_PROCESS(hook_process, options))
{
/*
* count number of arguments given in the hashable options,
* keys are: "arg1", "arg2", ...
*/
while (1)
{
snprintf (str_arg, sizeof (str_arg), "arg%d", num_args + 1);
if (!hashtable_has_key (HOOK_PROCESS(hook_process, options), str_arg))
break;
num_args++;
}
}
if (num_args > 0)
{
/*
* if at least one argument was found in hashtable option, the
* "command" contains only path to binary (without arguments), and
* the arguments are in hashtable
*/
exec_args = malloc ((num_args + 2) * sizeof (exec_args[0]));
if (exec_args)
{
exec_args[0] = HOOK_PROCESS(hook_process, command);
for (i = 1; i <= num_args; i++)
{
snprintf (str_arg, sizeof (str_arg), "arg%d", i);
exec_args[i] = (char *)hashtable_get (HOOK_PROCESS(hook_process, options),
str_arg);
}
exec_args[num_args + 1] = NULL;
}
}
else
{
/*
* if no arguments were found in hashtable, make an automatic split
* of command, like the shell does
*/
exec_args = string_split_shell (HOOK_PROCESS(hook_process, command));
}
if (exec_args)
{
if (weechat_debug_core >= 1)