[Pcsclite-cvs-commit] r6842 - in trunk/PCSC: . doc src

ludovic.rousseau at free.fr ludovic.rousseau at free.fr
Tue Feb 11 10:49:20 UTC 2014


Author: rousseau
Date: 2014-02-11 10:49:20 +0000 (Tue, 11 Feb 2014)
New Revision: 6842

Added:
   trunk/PCSC/doc/README.polkit
   trunk/PCSC/doc/org.debian.pcsc-lite.policy
   trunk/PCSC/src/auth.c
   trunk/PCSC/src/auth.h
Modified:
   trunk/PCSC/configure.ac
   trunk/PCSC/doc/Makefile.am
   trunk/PCSC/src/Makefile.am
   trunk/PCSC/src/winscard_svc.c
Log:
Add polkit support

See doc/README.polkit

Thanks to Nikos Mavrogiannopoulos for the patch
http://archives.neohapsis.com/archives/dev/muscle/2013-q4/0097.html


Modified: trunk/PCSC/configure.ac
===================================================================
--- trunk/PCSC/configure.ac	2014-02-11 09:45:54 UTC (rev 6841)
+++ trunk/PCSC/configure.ac	2014-02-11 10:49:20 UTC (rev 6842)
@@ -280,6 +280,29 @@
   PCSCLITE_FEATURES="${PCSCLITE_FEATURES} libusb"
 fi
 
+# --enable-polkit
+POLKIT_MINIMUM=0.111
+AC_ARG_ENABLE(polkit,
+	AS_HELP_STRING([--enable-polkit],
+		[Build with 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])
+		polkit_policy_dir=$($PKG_CONFIG polkit-gobject-1 --variable=policydir)
+		AC_SUBST(POLICY_DIR, [$polkit_policy_dir])
+	else
+	        use_polkit=no
+	        AC_MSG_ERROR([[
+*** 
+*** polkit >= $POLKIT_MINIMUM was not found. Access control will be disabled.
+*** You may get it from http://www.freedesktop.org/software/polkit/
+*** ]])
+	fi
+fi
+AM_CONDITIONAL(ENABLE_POLKIT, test "$use_polkit" != "no")
+
 # --with-systemdsystemunitdir=DIR
 AC_ARG_WITH([systemdsystemunitdir],
   AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
@@ -389,6 +412,8 @@
 PCSC_ARCH:           ${PCSC_ARCH}
 
 pcscd binary            ${PCSCD_BINARY}
+polkit support:         ${use_polkit}
+polkit policy dir:      ${polkit_policy_dir}
 libudev support:        ${use_libudev}
 libusb support:         ${use_libusb}
 USB drop directory:     ${usbdropdir}

Modified: trunk/PCSC/doc/Makefile.am
===================================================================
--- trunk/PCSC/doc/Makefile.am	2014-02-11 09:45:54 UTC (rev 6841)
+++ trunk/PCSC/doc/Makefile.am	2014-02-11 10:49:20 UTC (rev 6842)
@@ -3,13 +3,23 @@
 SUBDIRS = . example
 
 doc_DATA = \
-	README.DAEMON
+	README.DAEMON README.polkit
 
 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
 #	cp doxygen.css api/
+
+if ENABLE_POLKIT
+install-data-hook:
+	$(MKDIR_P) $(DESTDIR)/$(POLICY_DIR)
+	$(INSTALL_DATA) $(srcdir)/org.debian.pcsc-lite.policy $(DESTDIR)/$(POLICY_DIR)
+
+uninstall-hook:
+	rm $(DESTDIR)/$(POLICY_DIR)/org.debian.pcsc-lite.policy
+endif

Added: trunk/PCSC/doc/README.polkit
===================================================================
--- trunk/PCSC/doc/README.polkit	                        (rev 0)
+++ trunk/PCSC/doc/README.polkit	2014-02-11 10:49:20 UTC (rev 6842)
@@ -0,0 +1,39 @@
+When pcsc-lite is compiled using the --enable-polkit option then
+polkit will be used to control access to the pcsc-lite daemon.
+
+That allows more fine grained access control to smart cards that
+is tied to the system processes rather than solely depending on
+the smart card controls (e.g., only console users can access the 
+card and so on). 
+
+Polkit is documented at:
+http://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html
+
+A default polkit policy is shipped with pcsc-lite in
+org.debian.pcsc-lite.policy.  The policy file allows restricting access
+to the daemon as well as access to smart cards.
+
+Polkit allows for additional rules, e.g., restricting access to
+particular smart cards. The rules are javascript files placed
+in /usr/share/polkit-1/rules.d/. To make specific smart card 
+reader accessible by the web server (run as www-data user) you 
+may use the following rules:
+
+polkit.addRule(function(action, subject) {
+    if (action.id == "org.debian.pcsc-lite.access_card" &&
+        action.lookup("reader") == 'name of reader' &&
+        subject.user == "www-data") {
+            return polkit.Result.YES;
+    }
+});
+
+polkit.addRule(function(action, subject) {
+    if (action.id == "org.debian.pcsc-lite.access_pcsc" &&
+        subject.user == "www-data") {
+            return polkit.Result.YES;
+    }
+});
+
+
+Note that the name of the reader can be obtained using "opensc-tool -l"
+or "pcsc_scan".

Added: trunk/PCSC/doc/org.debian.pcsc-lite.policy
===================================================================
--- trunk/PCSC/doc/org.debian.pcsc-lite.policy	                        (rev 0)
+++ trunk/PCSC/doc/org.debian.pcsc-lite.policy	2014-02-11 10:49:20 UTC (rev 6842)
@@ -0,0 +1,30 @@
+<?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>smart-card</icon_name> -->
+
+  <action id="org.debian.pcsc-lite.access_pcsc">
+    <description>Access to the PC/SC daemon</description>
+    <message>Authentication is required to access the PC/SC daemon</message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>yes</allow_active>
+    </defaults>
+  </action>
+
+  <action id="org.debian.pcsc-lite.access_card">
+    <description>Access to the 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>

Modified: trunk/PCSC/src/Makefile.am
===================================================================
--- trunk/PCSC/src/Makefile.am	2014-02-11 09:45:54 UTC (rev 6841)
+++ trunk/PCSC/src/Makefile.am	2014-02-11 10:49:20 UTC (rev 6842)
@@ -35,6 +35,8 @@
 libpcsclite_la_LIBADD = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
 
 pcscd_SOURCES = \
+	auth.c \
+	auth.h \
 	atrhandler.c \
 	atrhandler.h \
 	configfile.h \
@@ -84,12 +86,14 @@
 	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

Added: trunk/PCSC/src/auth.c
===================================================================
--- trunk/PCSC/src/auth.c	                        (rev 0)
+++ trunk/PCSC/src/auth.c	2014-02-11 10:49:20 UTC (rev 6842)
@@ -0,0 +1,155 @@
+/*
+ * 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 <nmav at redhat.com>
+ */
+
+/**
+ * @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 <stdio.h>
+#include "debuglog.h"
+
+#include <errno.h>
+
+#if defined(HAVE_POLKIT) && defined(SO_PEERCRED)
+
+#include <polkit/polkit.h>
+
+/* Returns non zero when the client is authorized */
+unsigned IsClientAuthorized(int socket, const char* action, const char* reader)
+{
+	struct ucred cr;
+	socklen_t cr_len;
+	int ret;
+	PolkitSubject *subject;
+	PolkitAuthority *authority;
+	PolkitAuthorizationResult *result;
+	PolkitDetails *details;
+	GError *error = NULL;
+	char action_name[128];
+
+	snprintf(action_name, sizeof(action_name), "org.debian.pcsc-lite.%s", action);
+
+	cr_len = sizeof(cr);
+	ret = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
+	if (ret == -1)
+	{
+		int 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)
+	{
+		Log1(PCSC_LOG_CRITICAL, "polkit_authority_get_sync failed");
+		return 0;
+	}
+
+	subject = polkit_unix_process_new_for_owner(cr.pid, 0, cr.uid);
+	if (subject == NULL)
+	{
+		Log1(PCSC_LOG_CRITICAL, "polkit_unix_process_new_for_owner failed");
+		ret = 0;
+		goto cleanup1;
+	}
+
+	details = polkit_details_new();
+	if (details == NULL)
+	{
+		Log1(PCSC_LOG_CRITICAL, "polkit_details_new failed");
+		ret = 0;
+		goto cleanup0;
+	}
+
+	if (reader != NULL)
+		polkit_details_insert(details, "reader", reader);
+
+	result = polkit_authority_check_authorization_sync(authority, subject,
+		action_name, details,
+		POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+		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)
+	{
+		Log4(PCSC_LOG_CRITICAL,
+		     "Process %u (user: %u) is NOT authorized for action: %s",
+			(unsigned)cr.pid, (unsigned)cr.uid, action);
+	}
+
+	g_object_unref(subject);
+cleanup0:
+	g_object_unref(details);
+cleanup1:
+	g_object_unref(authority);
+
+	return ret;
+}
+
+#else
+
+int IsClientAuthorized(int socket, const char* action, const char* reader)
+{
+	return 1;
+}
+
+#endif

Added: trunk/PCSC/src/auth.h
===================================================================
--- trunk/PCSC/src/auth.h	                        (rev 0)
+++ trunk/PCSC/src/auth.h	2014-02-11 10:49:20 UTC (rev 6842)
@@ -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 <nmav at redhat.com>
+ *
+ */
+
+unsigned IsClientAuthorized(int socket, const char* action, const char* reader);

Modified: trunk/PCSC/src/winscard_svc.c
===================================================================
--- trunk/PCSC/src/winscard_svc.c	2014-02-11 09:45:54 UTC (rev 6841)
+++ trunk/PCSC/src/winscard_svc.c	2014-02-11 10:49:20 UTC (rev 6842)
@@ -68,6 +68,7 @@
 #include "readerfactory.h"
 #include "eventhandler.h"
 #include "simclist.h"
+#include "auth.h"
 
 /**
  * @brief Represents an Application Context on the Server side.
@@ -323,6 +324,16 @@
 	SCONTEXT * threadContext = (SCONTEXT *) newContext;
 	int32_t filedes = threadContext->dwClientID;
 
+	if (IsClientAuthorized(filedes, "access_pcsc", NULL) == 0)
+	{
+		Log1(PCSC_LOG_CRITICAL, "Rejected unauthorized PC/SC client");
+		goto exit;
+	}
+	else
+	{
+		Log1(PCSC_LOG_DEBUG, "Authorized PC/SC client");
+	}
+
 	Log3(PCSC_LOG_DEBUG, "Thread is started: dwClientID=%d, threadContext @%p",
 		threadContext->dwClientID, threadContext);
 
@@ -466,6 +477,16 @@
 				hCard = coStr.hCard;
 				dwActiveProtocol = coStr.dwActiveProtocol;
 
+				if (IsClientAuthorized(filedes, "access_card", coStr.szReader) == 0)
+				{
+					Log2(PCSC_LOG_CRITICAL, "Rejected unauthorized client for '%s'", coStr.szReader);
+					goto exit;
+				}
+				else
+				{
+					Log2(PCSC_LOG_DEBUG, "Authorized client for '%s'", coStr.szReader);
+				}
+
 				coStr.rv = SCardConnect(coStr.hContext, coStr.szReader,
 					coStr.dwShareMode, coStr.dwPreferredProtocols,
 					&hCard, &dwActiveProtocol);




More information about the Pcsclite-cvs-commit mailing list