using polkit

Nikos Mavrogiannopoulos <[email protected]>
Newsgroups gmane.comp.lib.muscle
Message-ID <[email protected]>
Hello,
 This patch adds polkit [0] support to pcscd, if the --with-polkit
configure option is specified. That allows more fine grained access
control to smart cards (e.g., only console users can access the card
and so on). It is a preliminary patch and the pcscd option with
very crude access control (allowed to access or not).  Please let me
know of any comments.

regards,
Nikos

[0].
http://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html

_______________________________________________
Muscle mailing list
[email protected]
http://lists.musclecard.com/mailman/listinfo/muscle_lists.musclecard.com
0001-Use-polkit-to-authorize-incoming-winscard-sessions.patch (text/x-patch, 12 KB)
From 65d67c78fcaa1d3593ecedc6a8a5219a3f6ad236 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <[email protected]>
Date: Tue, 17 Dec 2013 11:44:02 +0100
Subject: [PATCH] Use polkit to authorize incoming winscard sessions.

This patch adds the configure option --with-polkit that when
specified access to smart cards is only allowed if the polkit daemon
authorizes it.
---
 configure.ac                    |  20 ++++++
 doc/Makefile.am                 |   3 +-
 doc/org.debian.pcsc-lite.policy |  22 +++++++
 src/Makefile.am                 |   6 +-
 src/auth.c                      | 140 ++++++++++++++++++++++++++++++++++++++++
 src/auth.h                      |  35 ++++++++++
 src/pcscdaemon.c                |   6 ++
 src/winscard_svc.c              |   7 ++
 8 files changed, 237 insertions(+), 2 deletions(-)
 create mode 100644 doc/org.debian.pcsc-lite.policy
 create mode 100644 src/auth.c
 create mode 100644 src/auth.h

diff --git a/configure.ac b/configure.ac
index 7410f74..7efe46e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -280,6 +280,25 @@ if test x$use_libusb = xyes; then
   PCSCLITE_FEATURES="${PCSCLITE_FEATURES} libusb"
 fi
 
+POLKIT_MINIMUM=0.111
+AC_ARG_WITH(polkit,
+	AS_HELP_STRING([--with-polkit],
+		[Build without polkit support]),
+		use_polkit=$withval, use_polkit=no)
+if test "$use_polkit" != "no"; then
+	PKG_CHECK_MODULES(POLKIT, [polkit-gobject-1 >= $POLKIT_MINIMUM], [use_polkit=yes], [use_polkit=no])
+	if test "$use_polkit" != "no";then
+		AC_DEFINE([HAVE_POLKIT], 1, [Build polkit access control support])
+	else
+	        use_polkit=no
+	        AC_MSG_WARN([[
+*** 
+*** polkit >= $POLKIT_MINIMUM was not found. Access control will be disabled.
+*** You may get it from http://www.freedesktop.org/software/polkit/
+*** ]])
+	fi
+fi
+
 # --with-systemdsystemunitdir=DIR
 AC_ARG_WITH([systemdsystemunitdir],
   AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
@@ -389,6 +408,7 @@ PTHREAD_LIBS:        ${PTHREAD_LIBS}
 PCSC_ARCH:           ${PCSC_ARCH}
 
 pcscd binary            ${PCSCD_BINARY}
+polkit support:		${use_polkit}
 libudev support:        ${use_libudev}
 libusb support:         ${use_libusb}
 USB drop directory:     ${usbdropdir}
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 8c72357..7c5d402 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -8,7 +8,8 @@ doc_DATA = \
 man_MANS = pcscd.8 reader.conf.5 
 man_in = pcscd.8.in reader.conf.5.in
 
-EXTRA_DIST = $(doc_DATA) $(man_in) doxygen.conf.in formaticc.1
+EXTRA_DIST = $(doc_DATA) $(man_in) doxygen.conf.in formaticc.1 \
+	org.debian.pcsc-lite.policy
 
 doxygen:
 	rm -fr api ; cd .. ; doxygen doc/doxygen.conf
diff --git a/doc/org.debian.pcsc-lite.policy b/doc/org.debian.pcsc-lite.policy
new file mode 100644
index 0000000..b7a18a3
--- /dev/null
+++ b/doc/org.debian.pcsc-lite.policy
@@ -0,0 +1,22 @@
+<?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 PCSC-lite Project</vendor>
+  <vendor_url>http://pcsclite.alioth.debian.org/</vendor_url>
+<!--  <icon_name>drive-removable-media</icon_name> -->
+
+  
+  <action id="org.debian.pcsc-lite.access_card">
+    <description>Access a smart card</description>
+    <message>Authentication is required to access the smart card</message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>yes</allow_active>
+    </defaults>
+  </action>
+
+
+</policyconfig>
\ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
index 7db6f70..bec502b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -35,6 +35,8 @@ libpcsclite_la_CFLAGS = $(CFLAGS) $(PTHREAD_CFLAGS) -DLIBPCSCLITE -DSIMCLIST_NO_
 libpcsclite_la_LIBADD = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
 
 pcscd_SOURCES = \
+	auth.c \
+	auth.h \
 	atrhandler.c \
 	atrhandler.h \
 	configfile.h \
@@ -84,12 +86,14 @@ pcscd_SOURCES = \
 	winscard_svc.c \
 	winscard_svc.h
 pcscd_CFLAGS = $(CFLAGS) $(PTHREAD_CFLAGS) $(LIBUSB_CFLAGS) $(LIBUDEV_CFLAGS) \
+	$(POLKIT_CFLAGS) \
 	-DPCSCD -DSIMCLIST_NO_DUMPRESTORE
 pcscd_LDFLAGS = $(LDFLAGS) -export-dynamic
 pcscd_LDADD = \
 	$(PTHREAD_LIBS) $(COREFOUNDATION) \
 	$(LIBUSB_LIBS) $(IOKIT) $(LIBUDEV_LIBS) \
-	$(PTHREAD_LIBS) $(PTHREAD_CFLAGS)
+	$(PTHREAD_LIBS) $(PTHREAD_CFLAGS) \
+	$(POLKIT_LIBS) 
 
 fix-rights: install-sbinPROGRAMS
 	chgrp pcscd $(DESTDIR)$(sbindir)/pcscd
diff --git a/src/auth.c b/src/auth.c
new file mode 100644
index 0000000..286898e
--- /dev/null
+++ b/src/auth.c
@@ -0,0 +1,140 @@
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2013 Red Hat
+ *
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE.
+ *
+ * Author: Nikos Mavrogiannopoulos <[email protected]>
+ *
+ */
+
+/**
+ * @file
+ * @brief polkit authorization of clients
+ *
+ * IsClientAuthorized() checks whether the connecting client is authorized
+ * to access the resources using polkit.
+ */
+
+#include "config.h"
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/un.h>
+#include "debuglog.h"
+              
+#include <errno.h>
+
+#if defined(HAVE_POLKIT) && defined(SO_PEERCRED)
+
+extern unsigned AllowAuthInteraction;
+
+#include <polkit/polkit.h>
+
+#define ACTION_ID "org.debian.pcsc-lite.access_card"
+#define AUTH_TIMEOUT 15
+
+/* Returns non zero when the client is authorized */
+unsigned IsClientAuthorized(int socket)
+{
+	struct ucred cr;
+	socklen_t cr_len;
+	int e, ret;
+	PolkitSubject *subject;
+	PolkitAuthority *authority;
+	PolkitAuthorizationResult *result;
+	PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
+	GError *error = NULL;
+
+	if (AllowAuthInteraction != FALSE)
+		flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
+
+	cr_len = sizeof(cr);
+	ret = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
+	if (ret == -1) {
+		e = errno;
+		Log2(PCSC_LOG_CRITICAL,
+		     "Error obtaining client process credentials: %s", strerror(e));
+		return 0;
+	}
+
+	authority = polkit_authority_get_sync(NULL, NULL);
+	if (authority == NULL) {
+		Log3(PCSC_LOG_CRITICAL,
+		     "Error in %s:%d", __func__, __LINE__);
+		return 0;
+	}
+
+	subject = polkit_unix_process_new_for_owner(cr.pid, 0, cr.uid);
+	if (subject == NULL) {
+		Log3(PCSC_LOG_CRITICAL,
+		     "Error in %s:%d", __func__, __LINE__);
+		ret = 0;
+		goto cleanup1;
+	}
+
+	result = polkit_authority_check_authorization_sync(authority, subject,
+			ACTION_ID, NULL, /* PolkitDetails */
+			flags,
+			NULL,
+			&error);
+
+	if (result == NULL) {
+		Log2(PCSC_LOG_CRITICAL,
+		     "Error in authorization: %s", error->message);
+		g_error_free(error);
+		ret = 0;
+	} else {
+		if (polkit_authorization_result_get_is_authorized(result)) {
+			ret = 1;
+		} else {
+			ret = 0;
+		}
+	}
+
+	if (ret == 0) {
+		Log3(PCSC_LOG_CRITICAL,
+		     "Process %u (user: %u) is unauthorized to access pcscd", 
+		     	(unsigned)cr.pid, (unsigned)cr.uid);
+	}
+
+	g_object_unref(subject);
+cleanup1:
+	g_object_unref(authority);
+
+	return ret;
+}
+
+#else
+
+int IsClientAuthorized(int socket)
+{
+	return 1;
+}
+
+#endif
diff --git a/src/auth.h b/src/auth.h
new file mode 100644
index 0000000..2aa936a
--- /dev/null
+++ b/src/auth.h
@@ -0,0 +1,35 @@
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2013 Red Hat
+ *
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE.
+ *
+ * Author: Nikos Mavrogiannopoulos <[email protected]>
+ *
+ */
+
+unsigned IsClientAuthorized(int socket);
diff --git a/src/pcscdaemon.c b/src/pcscdaemon.c
index ba747e7..5d3b006 100644
--- a/src/pcscdaemon.c
+++ b/src/pcscdaemon.c
@@ -53,6 +53,7 @@
 #define FALSE 0
 #endif
 
+unsigned AllowAuthInteraction = FALSE;
 char AraKiri = FALSE;
 static char Init = TRUE;
 char AutoExit = FALSE;
@@ -175,6 +176,7 @@ int main(int argc, char **argv)
 		{"auto-exit", 0, NULL, 'x'},
 		{"reader-name-no-serial", 0, NULL, 'S'},
 		{"reader-name-no-interface", 0, NULL, 'I'},
+		{"allow-auth-interaction", 0, NULL, 1},
 		{NULL, 0, NULL, 0}
 	};
 #endif
@@ -221,6 +223,9 @@ int main(int argc, char **argv)
 					"force-reader-polling") == 0)
 					HPForceReaderPolling = optarg ? abs(atoi(optarg)) : 1;
 				break;
+			case 1:
+				AllowAuthInteraction = TRUE;
+				break;
 #endif
 			case 'c':
 				if (limited_rights)
@@ -789,6 +794,7 @@ static void print_usage (char const * const progname)
 	printf("  -c, --config		path to reader.conf\n");
 	printf("  -f, --foreground	run in foreground (no daemon),\n");
 	printf("			send logs to stdout instead of syslog\n");
+	printf("  --allow-auth-interaction Allow polkit to interact with the user\n");
 	printf("  -T, --color		force use of colored logs\n");
 	printf("  -h, --help		display usage information\n");
 	printf("  -H, --hotplug		ask the daemon to rescan the available readers\n");
diff --git a/src/winscard_svc.c b/src/winscard_svc.c
index fcb65a4..0995d69 100644
--- a/src/winscard_svc.c
+++ b/src/winscard_svc.c
@@ -42,6 +42,7 @@
 #include "readerfactory.h"
 #include "eventhandler.h"
 #include "simclist.h"
+#include "auth.h"
 
 /**
  * @brief Represents an Application Context on the Server side.
@@ -300,6 +301,12 @@ static void ContextThread(LPVOID newContext)
 	Log3(PCSC_LOG_DEBUG, "Thread is started: dwClientID=%d, threadContext @%p",
 		threadContext->dwClientID, threadContext);
 
+	if (IsClientAuthorized(filedes) == 0)
+	{
+		Log1(PCSC_LOG_CRITICAL, "Rejected unauthorized client");
+		goto exit;
+	}
+
 	while (1)
 	{
 		struct rxHeader header;
-- 
1.8.4.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.