Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UAPI socket for the macOS sandboxed Wireguard app #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions src/ipc-uapi-unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
#define SOCK_PATH RUNSTATEDIR "/wireguard/"
#define SOCK_SUFFIX ".sock"

static FILE *userspace_interface_file(const char *iface)
#ifdef __APPLE__
#define NET_EXT_APP_ID "com.wireguard.macos.network-extension"
#endif

static FILE *userspace_interface_file_at(const char *iface, const char *sock_path)
{
struct stat sbuf;
struct sockaddr_un addr = { .sun_family = AF_UNIX };
Expand All @@ -27,7 +31,7 @@ static FILE *userspace_interface_file(const char *iface)
errno = EINVAL;
if (strchr(iface, '/'))
goto out;
ret = snprintf(addr.sun_path, sizeof(addr.sun_path), SOCK_PATH "%s" SOCK_SUFFIX, iface);
ret = snprintf(addr.sun_path, sizeof(addr.sun_path), "%s%s" SOCK_SUFFIX, sock_path, iface);
if (ret < 0)
goto out;
ret = stat(addr.sun_path, &sbuf);
Expand Down Expand Up @@ -61,15 +65,31 @@ static FILE *userspace_interface_file(const char *iface)
return f;
}

static bool userspace_has_wireguard_interface(const char *iface)
static FILE *userspace_interface_file(const char *iface) {
FILE *ret = userspace_interface_file_at(iface, SOCK_PATH);
#ifdef __APPLE__
if (ret) {
return ret;
}
char sock_path[PATH_MAX];
if (snprintf(sock_path, sizeof(sock_path), "%s/Library/Containers/" NET_EXT_APP_ID "/Data/", getenv("HOME")) < 0) {
return NULL;
}

ret = userspace_interface_file_at(iface, sock_path);
#endif
return ret;
}

static bool userspace_has_wireguard_interface_at(const char *iface, const char *sock_path)
{
struct stat sbuf;
struct sockaddr_un addr = { .sun_family = AF_UNIX };
int fd, ret;

if (strchr(iface, '/'))
return false;
if (snprintf(addr.sun_path, sizeof(addr.sun_path), SOCK_PATH "%s" SOCK_SUFFIX, iface) < 0)
if (snprintf(addr.sun_path, sizeof(addr.sun_path), "%s%s" SOCK_SUFFIX, sock_path, iface) < 0)
return false;
if (stat(addr.sun_path, &sbuf) < 0)
return false;
Expand All @@ -88,15 +108,32 @@ static bool userspace_has_wireguard_interface(const char *iface)
return true;
}

static int userspace_get_wireguard_interfaces(struct string_list *list)
static bool userspace_has_wireguard_interface(const char *iface)
{
bool ret = userspace_has_wireguard_interface_at(iface, SOCK_PATH);
#ifdef __APPLE__
if (ret) {
return true;
}
char sock_path[PATH_MAX];
if (snprintf(sock_path, sizeof(sock_path), "%s/Library/Containers/" NET_EXT_APP_ID "/Data/", getenv("HOME")) < 0) {
return false;
}

ret = userspace_has_wireguard_interface_at(iface, sock_path);
#endif
return ret;
}

static int userspace_get_wireguard_interfaces_from(const char *sock_path, struct string_list *list)
{
DIR *dir;
struct dirent *ent;
size_t len;
char *end;
int ret = 0;

dir = opendir(SOCK_PATH);
dir = opendir(sock_path);
if (!dir)
return errno == ENOENT ? 0 : -errno;
while ((ent = readdir(dir))) {
Expand All @@ -117,3 +154,22 @@ static int userspace_get_wireguard_interfaces(struct string_list *list)
closedir(dir);
return ret;
}

static int userspace_get_wireguard_interfaces(struct string_list *list)
{
int ret = userspace_get_wireguard_interfaces_from(SOCK_PATH, list);
#ifdef __APPLE__
char sock_path[PATH_MAX];
int ret2 = snprintf(sock_path, sizeof(sock_path), "%s/Library/Containers/" NET_EXT_APP_ID "/Data/", getenv("HOME"));
if (ret2 < 0) {
goto out;
}

ret2 = userspace_get_wireguard_interfaces_from(sock_path, list);
out:
if (ret == 0) {
ret = ret2;
}
#endif
return ret;
}