diff --git a/src/modules/module-protocol-pulse/commands.h b/src/modules/module-protocol-pulse/commands.h index 8db5d8618..9dd1d749c 100644 --- a/src/modules/module-protocol-pulse/commands.h +++ b/src/modules/module-protocol-pulse/commands.h @@ -192,9 +192,15 @@ enum pulseaudio_command { COMMAND_MAX }; +enum command_access_flag { + COMMAND_ACCESS_WITHOUT_AUTH = (1 << 0), + COMMAND_ACCESS_WITHOUT_MANAGER = (1 << 1), +}; + struct command { const char *name; int (*run) (struct client *client, uint32_t command, uint32_t tag, struct message *msg); + uint32_t access; }; extern const struct command commands[COMMAND_MAX]; diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index 6eb6d98d5..f0fae517a 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -4856,12 +4856,12 @@ const struct command commands[COMMAND_MAX] = COMMAND(CREATE_RECORD_STREAM, do_create_record_stream), COMMAND(DELETE_RECORD_STREAM, do_delete_stream), COMMAND(EXIT, do_error_access), - COMMAND(AUTH, do_command_auth), - COMMAND(SET_CLIENT_NAME, do_set_client_name), + COMMAND(AUTH, do_command_auth, COMMAND_ACCESS_WITHOUT_AUTH | COMMAND_ACCESS_WITHOUT_MANAGER), + COMMAND(SET_CLIENT_NAME, do_set_client_name, COMMAND_ACCESS_WITHOUT_MANAGER), COMMAND(LOOKUP_SINK, do_lookup), COMMAND(LOOKUP_SOURCE, do_lookup), COMMAND(DRAIN_PLAYBACK_STREAM, do_drain_stream), - COMMAND(STAT, do_stat), + COMMAND(STAT, do_stat, COMMAND_ACCESS_WITHOUT_MANAGER), COMMAND(GET_PLAYBACK_LATENCY, do_get_playback_latency), COMMAND(CREATE_UPLOAD_STREAM, do_create_upload_stream), COMMAND(DELETE_UPLOAD_STREAM, do_delete_stream), diff --git a/src/modules/module-protocol-pulse/server.c b/src/modules/module-protocol-pulse/server.c index 7d5c1f428..15f56f432 100644 --- a/src/modules/module-protocol-pulse/server.c +++ b/src/modules/module-protocol-pulse/server.c @@ -91,12 +91,23 @@ static int handle_packet(struct client *client, struct message *msg) message_dump(SPA_LOG_LEVEL_INFO, msg); } - if (commands[command].run == NULL) { + const struct command *cmd = &commands[command]; + if (cmd->run == NULL) { res = -ENOTSUP; goto finish; } - res = commands[command].run(client, command, tag, msg); + if (!client->authenticated && !SPA_FLAG_IS_SET(cmd->access, COMMAND_ACCESS_WITHOUT_AUTH)) { + res = -EACCES; + goto finish; + } + + if (client->manager == NULL && !SPA_FLAG_IS_SET(cmd->access, COMMAND_ACCESS_WITHOUT_MANAGER)) { + res = -EACCES; + goto finish; + } + + res = cmd->run(client, command, tag, msg); finish: message_free(impl, msg, false, false);