mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-03-30 11:11:05 -04:00
Merge branch 'main' into 'main'
server: wl_client: introduce method for getting client security context See merge request wayland/wayland!460
This commit is contained in:
commit
444193a804
4 changed files with 74 additions and 0 deletions
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -129,6 +131,34 @@ wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid)
|
||||||
#error "Don't know how to read ucred on this platform"
|
#error "Don't know how to read ucred on this platform"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
wl_os_socket_peersec(int sockfd, char **security_context)
|
||||||
|
{
|
||||||
|
#if defined(SO_PEERSEC)
|
||||||
|
socklen_t len = NAME_MAX;
|
||||||
|
char *context = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
do {
|
||||||
|
char *new_context = realloc(context, len);
|
||||||
|
if (!new_context) {
|
||||||
|
free(context);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
context = new_context;
|
||||||
|
|
||||||
|
r = getsockopt(sockfd, SOL_SOCKET, SO_PEERSEC, context, &len);
|
||||||
|
if (r < 0 && errno != ERANGE) {
|
||||||
|
free(context);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (r < 0 && errno == ERANGE);
|
||||||
|
|
||||||
|
*security_context = context;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
wl_os_dupfd_cloexec(int fd, int minfd)
|
wl_os_dupfd_cloexec(int fd, int minfd)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ wl_os_socket_cloexec(int domain, int type, int protocol);
|
||||||
int
|
int
|
||||||
wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid);
|
wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid);
|
||||||
|
|
||||||
|
int
|
||||||
|
wl_os_socket_peersec(int sockfd, char **security_context);
|
||||||
|
|
||||||
int
|
int
|
||||||
wl_os_dupfd_cloexec(int fd, int minfd);
|
wl_os_dupfd_cloexec(int fd, int minfd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,10 @@ void
|
||||||
wl_client_get_credentials(const struct wl_client *client,
|
wl_client_get_credentials(const struct wl_client *client,
|
||||||
pid_t *pid, uid_t *uid, gid_t *gid);
|
pid_t *pid, uid_t *uid, gid_t *gid);
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_client_get_security_context(struct wl_client *client,
|
||||||
|
char **security_context);
|
||||||
|
|
||||||
int
|
int
|
||||||
wl_client_get_fd(struct wl_client *client);
|
wl_client_get_fd(struct wl_client *client);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ struct wl_client {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
|
char *security_context;
|
||||||
bool error;
|
bool error;
|
||||||
struct wl_priv_signal resource_created_signal;
|
struct wl_priv_signal resource_created_signal;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
@ -654,6 +655,40 @@ wl_client_get_credentials(const struct wl_client *client,
|
||||||
*gid = client->gid;
|
*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
|
/** Get the file descriptor for the client
|
||||||
*
|
*
|
||||||
* \param client The display object
|
* \param client The display object
|
||||||
|
|
@ -1019,6 +1054,8 @@ wl_client_destroy(struct wl_client *client)
|
||||||
|
|
||||||
wl_priv_signal_final_emit(&client->destroy_late_signal, client);
|
wl_priv_signal_final_emit(&client->destroy_late_signal, client);
|
||||||
|
|
||||||
|
free(client->security_context);
|
||||||
|
|
||||||
wl_list_remove(&client->resource_created_signal.listener_list);
|
wl_list_remove(&client->resource_created_signal.listener_list);
|
||||||
|
|
||||||
if (client->data_dtor)
|
if (client->data_dtor)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue