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.
This commit is contained in:
Marek Marczykowski-Górecki 2018-02-16 04:20:31 +01:00
parent ff2e2dbc22
commit 50412a8a8f
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 33 additions and 2 deletions

View File

@ -24,6 +24,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#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:;
}

View File

@ -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);