[glib: 10/12] gio: tests AF_UNIX socket credentials on win32
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 10/12] gio: tests AF_UNIX socket credentials on win32
- Date: Wed, 26 Jan 2022 15:11:49 +0000 (UTC)
commit e796124b31aa6cf07ba0b34de5626fd20ea3fa58
Author: Marc-André Lureau <marcandre lureau redhat com>
Date: Wed Jan 19 20:39:59 2022 +0400
gio: tests AF_UNIX socket credentials on win32
Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>
gio/tests/socket.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 117 insertions(+), 5 deletions(-)
---
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index 6f6553d6d..250ec648a 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -2102,7 +2102,118 @@ client_setup_thread (gpointer user_data)
return NULL;
}
-#ifdef G_OS_UNIX
+#ifdef G_OS_WIN32
+/*
+ * _g_win32_socketpair:
+ *
+ * Create a pair of connected sockets, similar to POSIX/BSD socketpair().
+ *
+ * Windows does not (yet) provide a socketpair() function. However, since the
+ * introduction of AF_UNIX sockets, it is possible to implement a fairly close
+ * function.
+ */
+static gint
+_g_win32_socketpair (gint domain,
+ gint type,
+ gint protocol,
+ gint sv[2])
+{
+ struct sockaddr_un addr = { 0, };
+ socklen_t socklen;
+ SOCKET listener = INVALID_SOCKET;
+ SOCKET client = INVALID_SOCKET;
+ SOCKET server = INVALID_SOCKET;
+ gchar *path = NULL;
+ int tmpfd, rv = -1;
+ u_long arg, br;
+
+ g_return_val_if_fail (sv != NULL, -1);
+
+ addr.sun_family = AF_UNIX;
+ socklen = sizeof (addr);
+
+ tmpfd = g_file_open_tmp (NULL, &path, NULL);
+ if (tmpfd == -1)
+ {
+ WSASetLastError (WSAEACCES);
+ goto out;
+ }
+
+ g_close (tmpfd, NULL);
+
+ if (strlen (path) >= sizeof (addr.sun_path))
+ {
+ WSASetLastError (WSAEACCES);
+ goto out;
+ }
+
+ strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
+
+ listener = socket (domain, type, protocol);
+ if (listener == INVALID_SOCKET)
+ goto out;
+
+ if (DeleteFile (path) == 0)
+ {
+ if (GetLastError () != ERROR_FILE_NOT_FOUND)
+ goto out;
+ }
+
+ if (bind (listener, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR)
+ goto out;
+
+ if (listen (listener, 1) == SOCKET_ERROR)
+ goto out;
+
+ client = socket (domain, type, protocol);
+ if (client == INVALID_SOCKET)
+ goto out;
+
+ arg = 1;
+ if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR)
+ goto out;
+
+ if (connect (client, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR &&
+ WSAGetLastError () != WSAEWOULDBLOCK)
+ goto out;
+
+ server = accept (listener, NULL, NULL);
+ if (server == INVALID_SOCKET)
+ goto out;
+
+ arg = 0;
+ if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR)
+ goto out;
+
+ if (WSAIoctl (server, SIO_AF_UNIX_GETPEERPID,
+ NULL, 0U,
+ &arg, sizeof (arg), &br,
+ NULL, NULL) == SOCKET_ERROR || arg != GetCurrentProcessId ())
+ {
+ WSASetLastError (WSAEACCES);
+ goto out;
+ }
+
+ sv[0] = server;
+ server = INVALID_SOCKET;
+ sv[1] = client;
+ client = INVALID_SOCKET;
+ rv = 0;
+
+ out:
+ if (listener != INVALID_SOCKET)
+ closesocket (listener);
+ if (client != INVALID_SOCKET)
+ closesocket (client);
+ if (server != INVALID_SOCKET)
+ closesocket (server);
+
+ DeleteFile (path);
+ g_free (path);
+ return rv;
+}
+#endif /* G_OS_WIN32 */
+
static void
test_credentials_unix_socketpair (void)
{
@@ -2112,7 +2223,11 @@ test_credentials_unix_socketpair (void)
GError *error = NULL;
GCredentials *creds;
+#ifdef G_OS_WIN32
+ status = _g_win32_socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
+#else
status = socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
+#endif
g_assert_cmpint (status, ==, 0);
sock = g_socket_new_from_fd (fds[0], &error);
@@ -2133,10 +2248,9 @@ test_credentials_unix_socketpair (void)
}
g_object_unref (sock);
- close (fds[1]);
+ g_close (fds[1], NULL);
}
#endif
-#endif
int
main (int argc,
@@ -2199,9 +2313,7 @@ main (int argc,
#if G_CREDENTIALS_SUPPORTED
g_test_add_func ("/socket/credentials/tcp_client", test_credentials_tcp_client);
g_test_add_func ("/socket/credentials/tcp_server", test_credentials_tcp_server);
-#ifdef G_OS_UNIX
g_test_add_func ("/socket/credentials/unix_socketpair", test_credentials_unix_socketpair);
-#endif
#endif
return g_test_run();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]