commit 567ff24946fefab54ae477651b1747e471f9cafb
parent 0094aaffaf487555002907b661052a61e8dea5d2
Author: Christian Grothoff <grothoff@gnunet.org>
Date: Fri, 25 Oct 2024 16:41:48 +0200
Merge branch 'master' of git+ssh://git.taler.net/exchange
Diffstat:
6 files changed, 147 insertions(+), 41 deletions(-)
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
@@ -929,7 +929,7 @@ typedef void
* @param cb function to call on the result
* @param cb_cls closure for @a cb
* @param binary name of the binary to execute
- * @param ... NULL-terminated list of arguments for the @a binary,
+ * @param argv NULL-terminated list of arguments for the @a binary,
* usually starting with again the name of the binary
* @return handle to cancel the operation (and kill the helper)
*/
@@ -939,7 +939,7 @@ TALER_JSON_external_conversion_start (
TALER_JSON_JsonCallback cb,
void *cb_cls,
const char *binary,
- ...);
+ const char **argv);
/**
* Abort external conversion, killing the process and preventing
diff --git a/src/json/conversion.c b/src/json/conversion.c
@@ -298,12 +298,11 @@ TALER_JSON_external_conversion_start (const json_t *input,
TALER_JSON_JsonCallback cb,
void *cb_cls,
const char *binary,
- ...)
+ const char **argv)
{
struct TALER_JSON_ExternalConversion *ec;
struct GNUNET_DISK_PipeHandle *pipe_stdin;
struct GNUNET_DISK_PipeHandle *pipe_stdout;
- va_list ap;
ec = GNUNET_new (struct TALER_JSON_ExternalConversion);
ec->cb = cb;
@@ -312,15 +311,12 @@ TALER_JSON_external_conversion_start (const json_t *input,
GNUNET_assert (NULL != pipe_stdin);
pipe_stdout = GNUNET_DISK_pipe (GNUNET_DISK_PF_BLOCKING_WRITE);
GNUNET_assert (NULL != pipe_stdout);
- va_start (ap,
- binary);
- ec->helper = GNUNET_OS_start_process_va (GNUNET_OS_INHERIT_STD_ERR,
- pipe_stdin,
- pipe_stdout,
- NULL,
- binary,
- ap);
- va_end (ap);
+ ec->helper = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ERR,
+ pipe_stdin,
+ pipe_stdout,
+ NULL,
+ binary,
+ (char *const *) argv);
if (NULL == ec->helper)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c
@@ -1340,6 +1340,88 @@ TALER_KYCLOGIC_rule2priority (
/**
+ * Perform very primitive word splitting of a command.
+ *
+ * @args command command to split
+ * @args extra_args extra arguments to append after the word
+ * @returns NULL-terminated array of words
+ */
+static char **
+split_words (const char *command, const char **extra_args)
+{
+ unsigned int i = 0;
+ unsigned int j = 0;
+ unsigned int n = 0;
+ char **res = NULL;
+
+ /* Result is always NULL-terminated */
+ GNUNET_array_append (res, n, NULL);
+
+ /* Split command into words */
+ while (1)
+ {
+ char *c;
+
+ /* Skip initial whitespace before word */
+ while (' ' == command[i])
+ i++;
+
+ /* Start of new word */
+ j = i;
+
+ /* Scan to end of word */
+ while ( (0 != command[j]) && (' ' != command[j]) )
+ j++;
+
+ /* No new word found */
+ if (i == j)
+ break;
+
+ /* Append word to result */
+ c = GNUNET_malloc (j - i + 1);
+ memcpy (c, &command[i], j - i);
+ c[j - i] = 0;
+ res[n - 1] = c;
+ GNUNET_array_append (res, n, NULL);
+
+ /* Continue at end of word */
+ i = j;
+ }
+
+ /* Append extra args */
+ if (NULL != extra_args)
+ {
+ for (const char **m = extra_args; *m; m++)
+ {
+ res[n - 1] = GNUNET_strdup (*m);
+ GNUNET_array_append (res, n, NULL);
+ }
+ }
+
+ return res;
+}
+
+
+/**
+ * Free arguments allocated with split_words.
+ *
+ * @param args NULL-terminated array of strings to free.
+ */
+static void
+destroy_words (char **args)
+{
+ if (NULL == args)
+ return;
+ for (char **m = args; *m; m++)
+ {
+ GNUNET_free (*m);
+ *m = NULL;
+ }
+ GNUNET_free (args);
+}
+
+
+/**
* Run @a command with @a argument and return the
* respective output from stdout.
*
@@ -1357,6 +1439,12 @@ command_output (const char *command,
ssize_t ret;
int sout[2];
pid_t chld;
+ const char *extra_args[] = {
+ argument,
+ "-c",
+ cfg_filename,
+ NULL,
+ };
if (0 != pipe (sout))
{
@@ -1373,6 +1461,11 @@ command_output (const char *command,
}
if (0 == chld)
{
+ char **argv;
+
+ argv = split_words (command,
+ extra_args);
+
GNUNET_break (0 ==
close (sout[0]));
GNUNET_break (0 ==
@@ -1382,12 +1475,9 @@ command_output (const char *command,
STDOUT_FILENO));
GNUNET_break (0 ==
close (sout[1]));
- execlp (command,
- command,
- argument,
- "-c",
- cfg_filename,
- NULL);
+ execvp (argv[0],
+ argv);
+ destroy_words (argv);
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"exec",
command);
@@ -3750,6 +3840,13 @@ TALER_KYCLOGIC_run_aml_program2 (
{
json_t *input;
+ const char *extra_args[] = {
+ "-c",
+ cfg_filename,
+ NULL,
+ };
+
+ char **args;
input = GNUNET_JSON_PACK (
GNUNET_JSON_pack_allow_null (
@@ -3765,6 +3862,9 @@ TALER_KYCLOGIC_run_aml_program2 (
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Running AML program %s\n",
prog->command);
+ args = split_words (prog->command, extra_args);
+ GNUNET_assert (NULL != args);
+ GNUNET_assert (NULL != args[0]);
json_dumpf (input,
stderr,
JSON_INDENT (2));
@@ -3772,11 +3872,9 @@ TALER_KYCLOGIC_run_aml_program2 (
input,
&handle_aml_output,
aprh,
- prog->command,
- prog->command,
- "-c",
- cfg_filename,
- NULL);
+ args[0],
+ (const char **) args);
+ destroy_words (args);
json_decref (input);
}
return aprh;
diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c b/src/kyclogic/plugin_kyclogic_kycaid.c
@@ -967,16 +967,22 @@ handle_webhook_finished (void *cls,
resp);
break;
}
- wh->econ
- = TALER_JSON_external_conversion_start (
- j,
- &webhook_conversion_cb,
- wh,
- wh->pd->conversion_helper,
- wh->pd->conversion_helper,
- "-a",
- wh->pd->auth_token,
- NULL);
+ {
+ const char *argv[] = {
+ wh->pd->conversion_helper,
+ "-a",
+ wh->pd->auth_token,
+ NULL,
+ };
+
+ wh->econ
+ = TALER_JSON_external_conversion_start (
+ j,
+ &webhook_conversion_cb,
+ wh,
+ wh->pd->conversion_helper,
+ argv);
+ }
if (NULL == wh->econ)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c
@@ -1084,6 +1084,10 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph,
const json_t *j)
{
const struct TALER_KYCLOGIC_ProviderDetails *pd = ph->pd;
+ const char *argv[] = {
+ pd->conversion_binary,
+ NULL,
+ };
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Calling converter `%s' with JSON\n",
@@ -1096,8 +1100,7 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph,
&converted_proof_cb,
ph,
pd->conversion_binary,
- pd->conversion_binary,
- NULL);
+ argv);
if (NULL != ph->ec)
return;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/kyclogic/plugin_kyclogic_persona.c b/src/kyclogic/plugin_kyclogic_persona.c
@@ -1022,6 +1022,13 @@ start_conversion (const struct TALER_KYCLOGIC_ProviderDetails *pd,
TALER_JSON_JsonCallback cb,
void *cb_cls)
{
+ const char *argv[] = {
+ pd->conversion_binary,
+ "-a",
+ pd->auth_token,
+ NULL,
+ };
+
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Calling converter `%s' with JSON\n",
pd->conversion_binary);
@@ -1033,11 +1040,7 @@ start_conversion (const struct TALER_KYCLOGIC_ProviderDetails *pd,
cb,
cb_cls,
pd->conversion_binary,
- pd->conversion_binary,
- "-a",
- pd->auth_token,
- NULL
- );
+ argv);
}