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