From 50412a8a8f4e15e4c5256ddd5e51f1ea9360fd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Fri, 16 Feb 2018 04:20:31 +0100 Subject: [PATCH] qrexec: provide common function for handling service call Reduce code duplication by moving parsing of "QUBESRPC" magic command to one place. Call qubes-rpc-multiplexer directly with execve(), to avoid string expansions in its parameters. --- qrexec-lib/exec.c | 27 ++++++++++++++++++++++++++- qrexec-lib/libqrexec-utils.h | 8 +++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/qrexec-lib/exec.c b/qrexec-lib/exec.c index 890c242..90b54d6 100644 --- a/qrexec-lib/exec.c +++ b/qrexec-lib/exec.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include "qrexec.h" #include "libqrexec-utils.h" static do_exec_t *exec_func = NULL; @@ -31,6 +33,29 @@ void register_exec_func(do_exec_t *func) { exec_func = func; } +void exec_qubes_rpc_if_requested(char *prog, char *const envp[]) { + /* avoid calling qubes-rpc-multiplexer through shell */ + if (strncmp(prog, RPC_REQUEST_COMMAND, RPC_REQUEST_COMMAND_LEN) == 0) { + char *tok; + char *argv[16]; // right now 6 are used, but allow future extensions + size_t i = 0; + + tok=strtok(prog, " "); + do { + if (i >= sizeof(argv)/sizeof(argv[0])-1) { + fprintf(stderr, "To many arguments to %s\n", RPC_REQUEST_COMMAND); + exit(1); + } + argv[i++] = tok; + } while ((tok=strtok(NULL, " "))); + argv[i] = NULL; + argv[0] = QUBES_RPC_MULTIPLEXER_PATH; + execve(QUBES_RPC_MULTIPLEXER_PATH, argv, envp); + perror("exec qubes-rpc-multiplexer"); + exit(1); + } +} + void fix_fds(int fdin, int fdout, int fderr) { int i; @@ -68,7 +93,7 @@ void do_fork_exec(const char *cmdline, int *pid, int *stdin_fd, int *stdout_fd, fix_fds(inpipe[0], outpipe[1], 2); if (exec_func != NULL) - exec_func(cmdline); + exec_func((char*)cmdline); exit(-1); default:; } diff --git a/qrexec-lib/libqrexec-utils.h b/qrexec-lib/libqrexec-utils.h index bd34afc..dd225eb 100644 --- a/qrexec-lib/libqrexec-utils.h +++ b/qrexec-lib/libqrexec-utils.h @@ -33,8 +33,14 @@ struct buffer { #define WRITE_STDIN_BUFFERED 1 /* something still in the buffer */ #define WRITE_STDIN_ERROR 2 /* write error, errno set */ -typedef void (do_exec_t)(const char *); +typedef void (do_exec_t)(char *); void register_exec_func(do_exec_t *func); +/* + * exec() qubes-rpc-multiplexer if *prog* starts with magic "QUBESRPC" keyword, + * do not return in that case; pass *envp* to execve() as en environment + * otherwise, return false without any action + */ +void exec_qubes_rpc_if_requested(char *prog, char *const envp[]); void buffer_init(struct buffer *b); void buffer_free(struct buffer *b);