Add create_secure_client and create_client_socket

This commit is contained in:
Drew DeVault 2018-09-08 10:19:33 -04:00
parent 8932d17275
commit 3fa2d545de
4 changed files with 56 additions and 10 deletions

View file

@ -273,7 +273,7 @@ enum secure_feature {
};
struct feature_policy {
char *program;
char *command;
uint64_t permit_features;
uint64_t reject_features;
};

View file

@ -6,13 +6,15 @@
/** Returns a mask of all features this client is permitted to use */
uint64_t get_feature_policy_mask(struct wl_client *client);
/** Returns the policy for a program, or creates one if it doesn't exist. */
/** Returns the policy for a command, or creates one if it doesn't exist. */
struct feature_policy *get_feature_policy(
struct sway_config *config, const char *program);
struct sway_config *config, const char *command);
/** Creates a wayland client with a feature policy applied. */
/** Creates a wayland client with the appropriate feature policy. */
struct wl_client *create_secure_client(struct wl_display *display,
int fd, const struct feature_policy *policy);
int fd, const char *command);
bool create_client_socket(int sv[2]);
struct feature_name {
char *name;

View file

@ -1,4 +1,4 @@
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@ -57,6 +57,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
close(fd[0]);
if ((child = fork()) == 0) {
close(fd[1]);
execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL);
@ -74,6 +75,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed");
}
close(fd[1]); // close write
ssize_t s = 0;
while ((size_t)s < sizeof(pid_t)) {
s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s);

View file

@ -1,6 +1,9 @@
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include "sway/security.h"
struct feature_name feature_names[] = {
@ -15,19 +18,58 @@ struct feature_name feature_names[] = {
};
struct feature_policy *get_feature_policy(
struct sway_config *config, const char *program) {
if (!program) {
struct sway_config *config, const char *command) {
if (!command) {
return &config->default_policy;
}
struct feature_policy *policy;
for (int i = 0; i < config->feature_policies->length; ++i) {
policy = config->feature_policies->items[i];
if (strcmp(policy->program, program) == 0) {
if (strcmp(policy->command, command) == 0) {
return policy;
}
}
policy = calloc(1, sizeof(struct feature_policy));
policy->program = strdup(program);
policy->command = strdup(command);
return policy;
}
struct wl_client *create_secure_client(struct wl_display *display,
int fd, const char *command) {
struct feature_policy *policy;
int i;
for (i = 0; i < config->feature_policies->length; ++i) {
policy = config->feature_policies->items[i];
if (strcmp(policy->command, command) == 0) {
break;
}
}
if (i == config->feature_policies->length) {
policy = &config->default_policy;
}
// TODO: Something useful with policy
struct wl_client *client = wl_client_create(display, fd);
// TODO: Destroy listener
return client;
}
bool create_client_socket(int sv[2]) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0 || errno == EINVAL) {
return false;
}
int flags;
if ((flags = fcntl(sv[0], F_GETFD)) == -1) {
return false;
}
if ((fcntl(sv[0], F_SETFD, flags | FD_CLOEXEC)) == -1) {
return false;
}
if ((flags = fcntl(sv[1], F_GETFD)) == -1) {
return false;
}
if ((fcntl(sv[1], F_SETFD, flags | FD_CLOEXEC)) == -1) {
return false;
}
return true;
}