[wing/wip/security-descriptor] namedpipelistener: add parameter to set the security descriptor



commit 01572275d9e0813c25d8e9ca24a86af5657aa0bd
Author: Ignacio Casal Quinteiro <ignacio casal nice-software com>
Date:   Fri Sep 23 17:52:49 2016 +0200

    namedpipelistener: add parameter to set the security descriptor

 tests/named-pipe.c           |   11 +++++++++
 wing/wingnamedpipelistener.c |   47 ++++++++++++++++++++++++++++++++++++++++-
 wing/wingnamedpipelistener.h |    1 +
 3 files changed, 57 insertions(+), 2 deletions(-)
---
diff --git a/tests/named-pipe.c b/tests/named-pipe.c
index 0fc0c78..7e83eaf 100644
--- a/tests/named-pipe.c
+++ b/tests/named-pipe.c
@@ -31,12 +31,14 @@ test_add_named_pipe (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-good-named-pipe-name",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\gtest-bad-named-pipe-name",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
 
@@ -91,6 +93,7 @@ test_connect_basic (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -128,6 +131,7 @@ test_connect_before_accept (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -164,6 +168,7 @@ test_connect_sync (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-connect-sync",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -239,6 +244,7 @@ test_accept_cancel (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-cancel",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -273,6 +279,7 @@ test_connect_accept_cancel (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -326,6 +333,7 @@ test_multi_client_basic (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -533,6 +541,7 @@ test_read_write_basic (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -573,6 +582,7 @@ test_read_write_several_connections (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
@@ -623,6 +633,7 @@ test_read_write_same_time_several_connections (void)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
                                            NULL,
+                                           NULL,
                                            &error);
   g_assert_no_error (error);
 
diff --git a/wing/wingnamedpipelistener.c b/wing/wingnamedpipelistener.c
index 5d66c10..52b62e3 100644
--- a/wing/wingnamedpipelistener.c
+++ b/wing/wingnamedpipelistener.c
@@ -22,6 +22,7 @@
 #include "wingsource.h"
 
 #include <windows.h>
+#include <sddl.h>
 
 #define DEFAULT_PIPE_BUF_SIZE 4096
 
@@ -29,6 +30,8 @@ typedef struct
 {
   gchar *pipe_name;
   gunichar2 *pipe_namew;
+  gchar *security_descriptor;
+  gunichar2 *security_descriptorw;
   HANDLE handle;
   OVERLAPPED overlapped;
   GObject *source_object;
@@ -47,6 +50,7 @@ static GQuark source_quark = 0;
 
 static PipeData *
 pipe_data_new (const gchar *pipe_name,
+               const gchar *security_descriptor,
                GObject     *source_object)
 {
   PipeData *data;
@@ -54,6 +58,8 @@ pipe_data_new (const gchar *pipe_name,
   data = g_slice_new0 (PipeData);
   data->pipe_name = g_strdup (pipe_name);
   data->pipe_namew = g_utf8_to_utf16 (pipe_name, -1, NULL, NULL, NULL);
+  data->security_descriptor = g_strdup (security_descriptor);
+  data->security_descriptorw = g_utf8_to_utf16 (security_descriptor, -1, NULL, NULL, NULL);
   data->handle = INVALID_HANDLE_VALUE;
   data->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */
                                          TRUE, /* manual-reset event */
@@ -70,6 +76,8 @@ pipe_data_free (PipeData *data)
 {
   g_free (data->pipe_name);
   g_free (data->pipe_namew);
+  g_free (data->security_descriptor);
+  g_free (data->security_descriptorw);
   if (data->handle != INVALID_HANDLE_VALUE)
     CloseHandle (data->handle);
   CloseHandle (data->overlapped.hEvent);
@@ -132,6 +140,31 @@ static gboolean
 create_pipe_from_pipe_data (PipeData  *pipe_data,
                             GError   **error)
 {
+  SECURITY_ATTRIBUTES sa = { 0, };
+
+  if (pipe_data->security_descriptorw != NULL)
+    {
+      sa.nLength = sizeof (sa);
+
+      if (!ConvertStringSecurityDescriptorToSecurityDescriptorW (pipe_data->security_descriptorw,
+                                                                 SDDL_REVISION_1,
+                                                                 &sa.lpSecurityDescriptor,
+                                                                 NULL))
+        {
+          int errsv = GetLastError ();
+          gchar *emsg = g_win32_error_message (errsv);
+
+          g_set_error (error,
+                       G_IO_ERROR,
+                       g_io_error_from_win32_error (errsv),
+                       "Could not convert the security descriptor '%s': %s",
+                       pipe_data->security_descriptor, emsg);
+          g_free (emsg);
+
+          return FALSE;
+        }
+    }
+
   /* Set event as signaled */
   SetEvent(pipe_data->overlapped.hEvent);
 
@@ -144,7 +177,11 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
                                         PIPE_UNLIMITED_INSTANCES,
                                         DEFAULT_PIPE_BUF_SIZE,
                                         DEFAULT_PIPE_BUF_SIZE,
-                                        0, NULL);
+                                        0,
+                                        pipe_data->security_descriptorw != NULL ? &sa : NULL);
+
+  if (sa.lpSecurityDescriptor != NULL)
+    LocalFree (sa.lpSecurityDescriptor);
 
   if (pipe_data->handle == INVALID_HANDLE_VALUE)
     {
@@ -193,12 +230,17 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
  * wing_named_pipe_listener_add_named_pipe:
  * @listener: a #WingNamedPipeListener.
  * @pipe_name: a name for the pipe.
+ * @security_descriptor: (allow-none): a security descriptor or %NULL.
  * @source_object: (allow-none): Optional #GObject identifying this source
  * @error: #GError for error reporting, or %NULL to ignore.
  *
  * Adds @named_pipe to the set of named pipes that we try to accept clients
  * from.
  *
+ * @security_descriptor must be of the format specified by Microsoft:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
+ * or set to %NULL to not set any security descriptor to the pipe.
+ *
  * @source_object will be passed out in the various calls
  * to accept to identify this particular source, which is
  * useful if you're listening on multiple pipes and do
@@ -211,6 +253,7 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
 gboolean
 wing_named_pipe_listener_add_named_pipe (WingNamedPipeListener  *listener,
                                          const gchar            *pipe_name,
+                                         const gchar            *security_descriptor,
                                          GObject                *source_object,
                                          GError                **error)
 {
@@ -222,7 +265,7 @@ wing_named_pipe_listener_add_named_pipe (WingNamedPipeListener  *listener,
 
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
-  pipe_data = pipe_data_new (pipe_name, source_object);
+  pipe_data = pipe_data_new (pipe_name, security_descriptor, source_object);
   if (!create_pipe_from_pipe_data (pipe_data, error))
     {
       pipe_data_free (pipe_data);
diff --git a/wing/wingnamedpipelistener.h b/wing/wingnamedpipelistener.h
index a24cb52..982f36b 100644
--- a/wing/wingnamedpipelistener.h
+++ b/wing/wingnamedpipelistener.h
@@ -57,6 +57,7 @@ WingNamedPipeListener    *wing_named_pipe_listener_new            (void);
 WING_AVAILABLE_IN_ALL
 gboolean                  wing_named_pipe_listener_add_named_pipe (WingNamedPipeListener  *listener,
                                                                    const gchar            *pipe_name,
+                                                                   const gchar            
*security_descriptor,
                                                                    GObject                *source_object,
                                                                    GError                **error);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]