Skip to content

Commit

Permalink
Allow specifying a username in service config
Browse files Browse the repository at this point in the history
This also dramatically improves the configuration parser.  Configuration
files now use a strict subset of TOML rather than an ad-hoc format with
no validation.

Fixes: QubesOS/qubes-issues#6354
Fixes: QubesOS/qubes-issues#8153
  • Loading branch information
DemiMarie committed Apr 26, 2023
1 parent 2d1baa9 commit 49ab526
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 43 deletions.
9 changes: 8 additions & 1 deletion agent/qrexec-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ static int wait_for_session_maybe(char *cmdline) {
int stdin_pipe[2];
int wait_for_session = 0;
int ret = 0;
char *user = NULL;
sigset_t sigmask;

cmd = parse_qubes_rpc_command(cmdline, true);
Expand All @@ -544,7 +545,13 @@ static int wait_for_session_maybe(char *cmdline) {
goto out;

/* load service config - if it fails, use initial value */
load_service_config(cmd, &wait_for_session);
if (load_service_config(cmd, &wait_for_session, &user) < 0)
return 0;

if (user) {
free(cmd->username);
cmd->username = user;
}

if (!wait_for_session)
/* setting not set, or set to 0 */
Expand Down
3 changes: 2 additions & 1 deletion daemon/qrexec-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ static void wait_for_session_maybe(char *cmdline)
if (!cmd->service_descriptor)
goto out;

load_service_config(cmd, &wait_for_session);
char *user = NULL;
load_service_config(cmd, &wait_for_session, &user);
if (!wait_for_session)
goto out;

Expand Down
2 changes: 1 addition & 1 deletion libqrexec/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ endif


all: libqrexec-utils.so
libqrexec-utils.so.$(SO_VER): unix-server.o ioall.o buffer.o exec.o txrx-vchan.o write-stdin.o replace.o remote.o process_io.o log.o
libqrexec-utils.so.$(SO_VER): unix-server.o ioall.o buffer.o exec.o txrx-vchan.o write-stdin.o replace.o remote.o process_io.o log.o toml.o
$(CC) $(LDFLAGS) -Wl,-soname,$@ -o $@ $^ $(VCHANLIBS)

libqrexec-utils.so: libqrexec-utils.so.$(SO_VER)
Expand Down
37 changes: 3 additions & 34 deletions libqrexec/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ static int find_file(
}
return -1;
}

int load_service_config(const struct qrexec_parsed_command *cmd,
int *wait_for_session) {
int *wait_for_session, char **user) {
assert(cmd->service_descriptor);
assert(*user == NULL);

const char *config_path = getenv("QUBES_RPC_CONFIG_PATH");
if (!config_path)
Expand All @@ -270,38 +270,7 @@ int load_service_config(const struct qrexec_parsed_command *cmd,
if (ret < 0)
return 0;

char config[MAX_CONFIG_SIZE];
char *config_iter = config;
FILE *config_file;
size_t read_count;
char *current_line;

config_file = fopen(config_full_path, "re");
if (!config_file) {
PERROR("Failed to load %s", config_full_path);
return -1;
}

read_count = fread(config, 1, sizeof(config)-1, config_file);

if (ferror(config_file)) {
fclose(config_file);
return -1;
}

// config is a text file, should not have \0 inside; but when it has, part
// after it will be ignored
config[read_count] = 0;

while ((current_line = strsep(&config_iter, "\n"))) {
// ignore comments
if (current_line[0] == '#')
continue;
sscanf(current_line, "wait-for-session=%d", wait_for_session);
}

fclose(config_file);
return 1;
return qubes_toml_config_parse(config_full_path, wait_for_session, user);
}

struct qrexec_parsed_command *parse_qubes_rpc_command(
Expand Down
8 changes: 4 additions & 4 deletions libqrexec/libqrexec-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,15 @@ struct qrexec_parsed_command *parse_qubes_rpc_command(
const char *cmdline, bool strip_username);
void destroy_qrexec_parsed_command(struct qrexec_parsed_command *cmd);

/* Load service configuration, currently only wait-for-session option
* supported.
/* Load service configuration.
*
* Return:
* 1 - config successfuly loaded
* 0 - config not found
* -1 - other error
*/
int load_service_config(const struct qrexec_parsed_command *cmd_name,
int *wait_for_session);
int *wait_for_session, char **user);

typedef void (do_exec_t)(const char *cmdline, const char *user);
void register_exec_func(do_exec_t *func);
Expand Down Expand Up @@ -280,8 +279,9 @@ int process_io(const struct process_io_request *req);


void qrexec_log(int level, int errnoval, const char *file, int line,
const char *func, const char *fmt, ...);
const char *func, const char *fmt, ...) __attribute__((format(printf, 6, 7)));

void setup_logging(const char *program_name);
int qubes_toml_config_parse(const char *config_full_path, int *wait_for_session, char **user);

#endif /* _LIBQREXEC_UTILS_H */
2 changes: 1 addition & 1 deletion libqrexec/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ int handle_remote_data(
/* remote process exited, so there is no sense to send any data
* to it */
if (hdr.len < sizeof(*status)) {
LOG(ERROR, "MSG_DATA_EXIT_CODE too short: " PRIu32 " < %zu",
LOG(ERROR, "MSG_DATA_EXIT_CODE too short: %u < %zu",
hdr.len, sizeof(*status));
*status = 255;
} else
Expand Down
Loading

0 comments on commit 49ab526

Please sign in to comment.