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
From 1cebd3b07a2dd0c0fff43fcc721e0726a1e3c1d8 Mon Sep 17 00:00:00 2001
From: Mike Gorse <mgo...@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
_______________________________________________
This message was sent via the BRLTTY mailing list.
To post a message, send an e-mail to: BRLTTY@mielke.cc
For general information, go to: http://mielke.cc/mailman/listinfo/brltty