server: wl_client: introduce method for getting client security context

Introduces a function wl_client_get_security_context for obtaining the
security context of a connected client by using SO_PEERSEC on supported
systems. Returns NULL for unsupported systems (inline with behaviour of
e.g. Linux attempting to get a security context for a client that does
not exist, which is a valid state).

Signed-off-by: Rahul Sandhu <nvraxn@gmail.com>
This commit is contained in:
Rahul Sandhu 2025-02-23 20:29:31 +00:00
parent 1ab6b693b1
commit 5ed36d2b44
4 changed files with 74 additions and 0 deletions

View file

@ -82,6 +82,7 @@ struct wl_client {
pid_t pid;
uid_t uid;
gid_t gid;
char *security_context;
bool error;
struct wl_priv_signal resource_created_signal;
void *data;
@ -630,6 +631,40 @@ wl_client_get_credentials(const struct wl_client *client,
*gid = client->gid;
}
/** Return Security context for the client
*
* \param client The display object
* \param security_context Returns the security_context, or NULL if
* a security context could not be obtained.
*
* This function returns the security context for the given client.
* The credentials come from getsockopt() with SO_PEERSEC, on the
* client socket fd.
*
* Be aware that for clients that a compositor forks and execs and
* then connects using socketpair(), this function will return the
* security context for the compositor. The security context for
* the socketpair are set at creation time in the compositor.
*
* \memberof wl_client
*/
WL_EXPORT void
wl_client_get_security_context(struct wl_client *client,
char **security_context)
{
// Only initalise the security context if we have to
// so we don't waste heap space.
if (!client->security_context) {
if (wl_os_socket_peersec(wl_connection_get_fd(client->connection),
&client->security_context) != 0) {
*security_context = NULL;
return;
}
}
*security_context = client->security_context;
}
/** Get the file descriptor for the client
*
* \param client The display object
@ -981,6 +1016,8 @@ wl_client_destroy(struct wl_client *client)
wl_priv_signal_final_emit(&client->destroy_late_signal, client);
free(client->security_context);
wl_list_remove(&client->resource_created_signal.listener_list);
if (client->data_dtor)