pulse-server: add command access control

By default require that a client is authenticated and
has a manager to be allowed to run a command.

Specially:
 * AUTH requires nothing
 * SET_CLIENT_NAME and STAT only require authentication
This commit is contained in:
Barnabás Pőcze 2021-12-30 21:36:04 +01:00
parent 92abc7b7ad
commit 1c3e45a584
3 changed files with 22 additions and 5 deletions

View file

@ -192,9 +192,15 @@ enum pulseaudio_command {
COMMAND_MAX COMMAND_MAX
}; };
enum command_access_flag {
COMMAND_ACCESS_WITHOUT_AUTH = (1 << 0),
COMMAND_ACCESS_WITHOUT_MANAGER = (1 << 1),
};
struct command { struct command {
const char *name; const char *name;
int (*run) (struct client *client, uint32_t command, uint32_t tag, struct message *msg); int (*run) (struct client *client, uint32_t command, uint32_t tag, struct message *msg);
uint32_t access;
}; };
extern const struct command commands[COMMAND_MAX]; extern const struct command commands[COMMAND_MAX];

View file

@ -4856,12 +4856,12 @@ const struct command commands[COMMAND_MAX] =
COMMAND(CREATE_RECORD_STREAM, do_create_record_stream), COMMAND(CREATE_RECORD_STREAM, do_create_record_stream),
COMMAND(DELETE_RECORD_STREAM, do_delete_stream), COMMAND(DELETE_RECORD_STREAM, do_delete_stream),
COMMAND(EXIT, do_error_access), COMMAND(EXIT, do_error_access),
COMMAND(AUTH, do_command_auth), COMMAND(AUTH, do_command_auth, COMMAND_ACCESS_WITHOUT_AUTH | COMMAND_ACCESS_WITHOUT_MANAGER),
COMMAND(SET_CLIENT_NAME, do_set_client_name), COMMAND(SET_CLIENT_NAME, do_set_client_name, COMMAND_ACCESS_WITHOUT_MANAGER),
COMMAND(LOOKUP_SINK, do_lookup), COMMAND(LOOKUP_SINK, do_lookup),
COMMAND(LOOKUP_SOURCE, do_lookup), COMMAND(LOOKUP_SOURCE, do_lookup),
COMMAND(DRAIN_PLAYBACK_STREAM, do_drain_stream), 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(GET_PLAYBACK_LATENCY, do_get_playback_latency),
COMMAND(CREATE_UPLOAD_STREAM, do_create_upload_stream), COMMAND(CREATE_UPLOAD_STREAM, do_create_upload_stream),
COMMAND(DELETE_UPLOAD_STREAM, do_delete_stream), COMMAND(DELETE_UPLOAD_STREAM, do_delete_stream),

View file

@ -91,12 +91,23 @@ static int handle_packet(struct client *client, struct message *msg)
message_dump(SPA_LOG_LEVEL_INFO, 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; res = -ENOTSUP;
goto finish; 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: finish:
message_free(impl, msg, false, false); message_free(impl, msg, false, false);