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

>From 65d67c78fcaa1d3593ecedc6a8a5219a3f6ad236 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <n...@redhat.com>
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 <n...@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 "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 <n...@redhat.com>
+ *
+ */
+
+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

_______________________________________________
Muscle mailing list
Muscle@lists.musclecard.com
http://lists.musclecard.com/mailman/listinfo/muscle_lists.musclecard.com

Reply via email to