[BRLTTY] [patch] allow authentication via polkit

Mike Gorse mgorse at alum.wpi.edu
Thu Jan 28 10:22:41 EST 2016


I have written a patch to allow polkit-based authentication for brlapi. 
The policy file that I'm including will allow an active (local) user while 
not allowing an inactive/remote user to authenticate. This allows a local 
user to just connect a Braille display and have it work, at least for a 
USB display, without the user needing to be added to a group in order to 
read the key file, while still not allowing a remote user to authenticate.

It shouldn't have any effect unless Auth=polkit is passed.

A couple of things:

- The policy file belongs in $(datadir)/polkit-1/actions, but I haven't 
added a rule to install it (wasn't sure where I should put it or if I 
should create a new subdirectory under the main directory to place the 
file).

- I'm currently not passing 
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION. Probably we would 
want an async api in order to support this, but then a policy that asks 
for a password in order to allow access to the Braille display doesn't 
seem to make sense anyhow from an accessibility perspective, so I think 
that it is just as well not to allow it.

- I could probably rework the patch to only use libdbus, rather than 
polkit-gobject, if people would prefer that.

Thanks,
-Mike
-------------- next part --------------
From 1cebd3b07a2dd0c0fff43fcc721e0726a1e3c1d8 Mon Sep 17 00:00:00 2001
From: Mike Gorse <mgorse at suse.com>
Date: Thu, 28 Jan 2016 07:54:31 -0600
Subject: [PATCH] Support authentication via polkit

---
 Programs/Makefile.in       |  2 +-
 Programs/auth.c            | 87 ++++++++++++++++++++++++++++++++++++++++++++++
 Programs/brlapi_protocol.h |  4 +--
 config.h.in                |  3 ++
 config.mk.in               |  6 +++-
 configure.ac               |  3 ++
 org.brltty.policy          | 19 ++++++++++
 7 files changed, 120 insertions(+), 4 deletions(-)
 create mode 100644 org.brltty.policy

diff --git a/Programs/Makefile.in b/Programs/Makefile.in
index 93f3a36..33b28ad 100644
--- a/Programs/Makefile.in
+++ b/Programs/Makefile.in
@@ -308,7 +308,7 @@ pid.$O:
 ###############################################################################
 
 auth.$O:
-	$(CC) $(LIBCFLAGS) -c $(SRC_DIR)/auth.c
+	$(CC) $(LIBCFLAGS) $(POLKIT_INCLUDES) -c $(SRC_DIR)/auth.c
 
 dataarea.$O:
 	$(CC) $(LIBCFLAGS) -c $(SRC_DIR)/dataarea.c
diff --git a/Programs/auth.c b/Programs/auth.c
index fe56020..321acac 100644
--- a/Programs/auth.c
+++ b/Programs/auth.c
@@ -55,6 +55,10 @@ typedef unsigned int gid_t;
 #include "parse.h"
 #include "auth.h"
 
+#ifdef USE_POLKIT
+#include <polkit/polkit.h>
+#endif
+
 /* peer credentials */
 #undef CAN_CHECK_CREDENTIALS
 
@@ -74,6 +78,12 @@ typedef struct {
 #endif /* __MINGW32__ */
 } MethodDescriptor_group;
 
+#ifdef USE_POLKIT
+typedef struct {
+  PolkitAuthority *authority;
+} MethodDescriptor_polkit;
+#endif
+
 #if defined(__MINGW32__)
 #define CAN_CHECK_CREDENTIALS
 
@@ -130,6 +140,7 @@ checkPeerGroup (PeerCredentials *credentials, const MethodDescriptor_group *grou
 #include <zone.h>
 #endif /* HAVE_GETZONEID */
 
+
 typedef ucred_t *PeerCredentials;
 
 static int
@@ -437,6 +448,73 @@ authGroup_server (AuthDescriptor *auth, FileDescriptor fd, void *data) {
   return getPeerCredentials(auth, fd) &&
          checkPeerGroup(&auth->peerCredentials, group);
 }
+
+#ifdef USE_POLKIT
+/* the polkit method */
+
+static void *
+authPolkit_initialize (const char *parameter) {
+  MethodDescriptor_polkit *polkit;
+  GError *error_local = NULL;
+
+  if ((polkit = malloc(sizeof(*polkit)))) {
+    polkit->authority = polkit_authority_get_sync (NULL, &error_local);
+    if (polkit->authority == NULL) {
+      g_error_free (error_local);
+      g_free (polkit);
+      return NULL;
+    }
+    return polkit;
+  } else {
+    logMallocError();
+  }
+
+  return NULL;
+}
+
+static void
+authPolkit_release (void *data) {
+  MethodDescriptor_polkit *polkit = data;
+  g_object_unref (polkit->authority);
+  free(polkit);
+}
+
+static int
+authPolkit_server (AuthDescriptor *auth, FileDescriptor fd, void *data) {
+  PolkitSubject *subject;
+  GError *error_local = NULL;
+
+  MethodDescriptor_polkit *polkit = data;
+  struct ucred cred;
+  socklen_t length = sizeof(cred);
+  PolkitAuthorizationResult *result;
+  int ret = 0;
+
+  if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &length) == -1) {
+    logSystemError("getsockopt[SO_PEERCRED]");
+    return 0;
+  }
+
+  logMessage(LOG_DEBUG, "Attempting to authenticate pid %d via polkit", cred.pid);
+  subject = polkit_unix_process_new_for_owner (cred.pid, -1, -1);
+  result = polkit_authority_check_authorization_sync (polkit->authority, subject,
+			"org.brltty.write-display",
+			NULL,
+			POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+			NULL,
+			&error_local);
+  if (result == NULL) {
+    logSystemError("Error checking polkit authentication");
+    g_error_free (error_local);
+    return FALSE;
+  }
+
+  ret = polkit_authorization_result_get_is_authorized (result);
+  g_object_unref (result);
+    logMessage(LOG_DEBUG, "polkit_authority_check_authorization_sync returned %d", ret);
+    return ret;
+}
+#endif /* USE_POLKIT */
 #endif /* CAN_CHECK_CREDENTIALS */
 
 /* general functions */
@@ -463,6 +541,15 @@ static const MethodDefinition methodDefinitions[] = {
     .client = NULL,
     .server = authGroup_server
   },
+
+#ifdef USE_POLKIT
+  { .name = "polkit",
+    .initialize = authPolkit_initialize,
+    .release = authPolkit_release,
+    .client = NULL,
+    .server = authPolkit_server
+  },
+#endif /* USE_POLKIT */
 #endif /* CAN_CHECK_CREDENTIALS */
 
   {.name = NULL}
diff --git a/Programs/brlapi_protocol.h b/Programs/brlapi_protocol.h
index 55a90bf..461231b 100644
--- a/Programs/brlapi_protocol.h
+++ b/Programs/brlapi_protocol.h
@@ -103,8 +103,8 @@ typedef struct {
 } brlapi_authServerPacket_t;
 
 #define BRLAPI_AUTH_NONE 'N' /**< No or implicit authorization              */
-#define BRLAPI_AUTH_KEY  'K' /**< Key authorization                         */
-#define BRLAPI_AUTH_CRED 'C' /**< Explicit socket credentials authorization */
+#define BRLAPI_AUTH_KEY    'K' /**< Key authorization                         */
+#define BRLAPI_AUTH_CRED   'C' /**< Explicit socket credentials authorization */
 
 /** Structure of error packets */
 typedef struct {
diff --git a/config.h.in b/config.h.in
index caa952f..4eee486 100644
--- a/config.h.in
+++ b/config.h.in
@@ -424,6 +424,9 @@ extern "C" {
 #undef USE_PKG_PORTS_MSDOS
 #undef USE_PKG_PORTS_WINDOWS
 
+/* Define this if polkit is to be enabled */
+#undef USE_POLKIT
+
 /* Define only one of the following curses packages. */
 #undef HAVE_PKG_CURSES
 #undef HAVE_PKG_NCURSES
diff --git a/config.mk.in b/config.mk.in
index b1ea111..6fe9f1d 100644
--- a/config.mk.in
+++ b/config.mk.in
@@ -102,6 +102,10 @@ DBUS_PACKAGE = @dbus_package@
 DBUS_INCLUDES = @dbus_includes@
 DBUS_LIBS = @dbus_libs@
 
+POLKIT_PACKAGE = @polkit_package@
+POLKIT_INCLUDES = @polkit_includes@
+POLKIT_LIBS = @polkit_libs@
+
 ICU_INCLUDES = @icu_includes@
 ICU_LIBS = @icu_libs@
 
@@ -244,7 +248,7 @@ LIBCXXFLAGS = $(CXXFLAGS) @LIBCXXFLAGS@
 
 LD = @LD@
 LDFLAGS = @LDFLAGS@
-LDLIBS = $(ICU_LIBS) $(SYSTEM_LIBS) @LIBS@
+LDLIBS = $(ICU_LIBS) $(SYSTEM_LIBS) $(POLKIT_LIBS) @LIBS@
 
 MKOBJ = @MKOBJ@
 MKMOD = @MKMOD@
diff --git a/configure.ac b/configure.ac
index b4382cd..89ef32d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1778,6 +1778,9 @@ BRLTTY_HAVE_PACKAGE([dbus], ["dbus-1 >= 1.0"], [dnl
 BRLTTY_ARG_DRIVER([screen], [Screen])
 BRLTTY_SUMMARY_ITEM([screen-driver], [default_screen_driver])
 
+BRLTTY_HAVE_PACKAGE([polkit], [polkit-gobject-1],
+AC_DEFINE(USE_POLKIT, 1, [if we should use PolicyKit]))
+
 BRLTTY_ARG_ENABLE(
    [relocatable-install],
    [installation using paths relative to the program directory])
diff --git a/org.brltty.policy b/org.brltty.policy
new file mode 100644
index 0000000..bc312c5
--- /dev/null
+++ b/org.brltty.policy
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+  <vendor>The BRLTTY developers</vendor>
+  <vendor_url>http://www.brltty.com/</vendor_url>
+
+  <action id="org.brltty.write-display">
+    <description>Write to the Braille display</description>
+    <message>Privileges are required to access the Braille display</message>
+    <defaults>
+      <allow_any>no</allow_any>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>yes</allow_active>
+    </defaults>
+  </action>
+
+</policyconfig>
-- 
2.6.2



More information about the BRLTTY mailing list