From 95c3e28af5216e1be61f99818f682b2e49c48fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 19 Jan 2022 20:35:45 +0400 Subject: [PATCH] gio: add G_CREDENTIALS_TYPE_WIN32_PID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Credentials are often used to check peer processes details. With AF_UNIX sockets on Windows, SIO_AF_UNIX_GETPEERPID can be used to retrive the peer PID. We will probably introduce more advanced mechanisms later on, though, but I am not a Windows API expert. Signed-off-by: Marc-André Lureau --- gio/gcredentials.c | 11 +++++++++++ gio/gcredentialsprivate.h | 9 +++++++++ gio/gioenums.h | 2 ++ gio/gsocket.c | 21 +++++++++++++++++++++ gio/tests/credentials.c | 24 ++++++++++++++++++++++++ 5 files changed, 67 insertions(+) diff --git a/gio/gcredentials.c b/gio/gcredentials.c index 71d47b0f1..17378e881 100644 --- a/gio/gcredentials.c +++ b/gio/gcredentials.c @@ -72,6 +72,9 @@ * On Solaris (including OpenSolaris and its derivatives), the native * credential type is a `ucred_t`. This corresponds to * %G_CREDENTIALS_TYPE_SOLARIS_UCRED. + * + * Since GLib 2.72, on Windows, the native credentials may contain the PID of a + * process. This corresponds to %G_CREDENTIALS_TYPE_WIN32_PID. */ /** @@ -100,6 +103,8 @@ struct _GCredentials struct sockpeercred native; #elif G_CREDENTIALS_USE_SOLARIS_UCRED ucred_t *native; +#elif G_CREDENTIALS_USE_WIN32_PID + DWORD native; #else #ifdef __GNUC__ #pragma GCC diagnostic push @@ -188,6 +193,8 @@ g_credentials_init (GCredentials *credentials) credentials->native.gid = getegid (); #elif G_CREDENTIALS_USE_SOLARIS_UCRED credentials->native = ucred_get (P_MYID); +#elif G_CREDENTIALS_USE_WIN32_PID + credentials->native = GetCurrentProcessId (); #endif } @@ -293,6 +300,8 @@ g_credentials_to_string (GCredentials *credentials) if (ret->str[ret->len - 1] == ',') ret->str[ret->len - 1] = '\0'; } +#elif G_CREDENTIALS_USE_WIN32_PID + g_string_append_printf (ret, "win32-pid:pid=%lu", credentials->native); #else g_string_append (ret, "unknown"); #endif @@ -600,6 +609,8 @@ g_credentials_get_unix_pid (GCredentials *credentials, ret = credentials->native.pid; #elif G_CREDENTIALS_USE_SOLARIS_UCRED ret = ucred_getpid (credentials->native); +#elif G_CREDENTIALS_USE_WIN32_PID + ret = credentials->native; #else #if G_CREDENTIALS_USE_APPLE_XUCRED diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h index eff1e9701..c09f9eceb 100644 --- a/gio/gcredentialsprivate.h +++ b/gio/gcredentialsprivate.h @@ -40,6 +40,7 @@ #undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED #undef G_CREDENTIALS_USE_SOLARIS_UCRED #undef G_CREDENTIALS_USE_APPLE_XUCRED +#undef G_CREDENTIALS_USE_WIN32_PID /* * G_CREDENTIALS_NATIVE_TYPE: @@ -171,6 +172,14 @@ void _g_credentials_set_local_peerid (GCredentials *credentials, pid_t pid); +#elif defined(_WIN32) +#define G_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_USE_WIN32_PID 1 +#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_WIN32_PID +#define G_CREDENTIALS_NATIVE_SIZE (sizeof (DWORD)) +#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1 +#define G_CREDENTIALS_HAS_PID 1 + #endif #endif /* __G_CREDENTIALS_PRIVATE_H__ */ diff --git a/gio/gioenums.h b/gio/gioenums.h index ff1f5f48a..caab3d72c 100644 --- a/gio/gioenums.h +++ b/gio/gioenums.h @@ -1441,6 +1441,7 @@ typedef enum * @G_CREDENTIALS_TYPE_SOLARIS_UCRED: The native credentials type is a `ucred_t`. Added in 2.40. * @G_CREDENTIALS_TYPE_NETBSD_UNPCBID: The native credentials type is a `struct unpcbid`. Added in 2.42. * @G_CREDENTIALS_TYPE_APPLE_XUCRED: The native credentials type is a `struct xucred`. Added in 2.66. + * @G_CREDENTIALS_TYPE_WIN32_PID: The native credentials type is a PID `DWORD`. Added in 2.72. * * Enumeration describing different kinds of native credential types. * @@ -1455,6 +1456,7 @@ typedef enum G_CREDENTIALS_TYPE_SOLARIS_UCRED, G_CREDENTIALS_TYPE_NETBSD_UNPCBID, G_CREDENTIALS_TYPE_APPLE_XUCRED, + G_CREDENTIALS_TYPE_WIN32_PID, } GCredentialsType; /** diff --git a/gio/gsocket.c b/gio/gsocket.c index 4e69d2797..1f2ff3864 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -76,6 +76,10 @@ #include "glibintl.h" #include "gioprivate.h" +#ifdef G_OS_WIN32 +#include "giowin32-afunix.h" +#endif + /** * SECTION:gsocket * @short_description: Low-level socket object @@ -6129,6 +6133,23 @@ g_socket_get_credentials (GSocket *socket, ucred_free (ucred); } } +#elif G_CREDENTIALS_USE_WIN32_PID + { + DWORD peerid, drc; + + if (WSAIoctl (socket->priv->fd, SIO_AF_UNIX_GETPEERPID, + NULL, 0U, + &peerid, sizeof(peerid), + /* Windows bug: always 0 https://github.com/microsoft/WSL/issues/4676 */ + &drc, + NULL, NULL) == 0) + { + ret = g_credentials_new (); + g_credentials_set_native (ret, + G_CREDENTIALS_TYPE_WIN32_PID, + &peerid); + } + } #else #error "G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED is set but this is no code for this platform" #endif diff --git a/gio/tests/credentials.c b/gio/tests/credentials.c index 2b0f1f787..070019f1c 100644 --- a/gio/tests/credentials.c +++ b/gio/tests/credentials.c @@ -25,6 +25,28 @@ #include #include +#ifdef G_OS_WIN32 + +static void +test_basic (void) +{ + GCredentials *creds = g_credentials_new (); + gchar *stringified; + DWORD *pid; + + stringified = g_credentials_to_string (creds); + g_test_message ("%s", stringified); + g_free (stringified); + + pid = g_credentials_get_native (creds, + G_CREDENTIALS_TYPE_WIN32_PID); + g_assert_cmpuint (*pid, ==, GetCurrentProcessId ()); + + g_object_unref (creds); +} + +#else + static void test_basic (void) { @@ -177,6 +199,8 @@ test_basic (void) g_object_unref (other); } +#endif /* !G_OS_WIN32 */ + int main (int argc, char *argv[])