pcsc-lite 1.9.4
auth.c
Go to the documentation of this file.
1/*
2 * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
3 *
4 * Copyright (C) 2013 Red Hat
5 *
6 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 * DAMAGE.
30 *
31 * Author: Nikos Mavrogiannopoulos <nmav@redhat.com>
32 */
33
42#include "config.h"
43#define _GNU_SOURCE
44#include <sys/types.h>
45#include <sys/socket.h>
46#include <sys/ioctl.h>
47#include <sys/un.h>
48#include <stdio.h>
49#include "debuglog.h"
50#include "auth.h"
51
52#include <errno.h>
53
54#if defined(HAVE_POLKIT) && defined(SO_PEERCRED)
55
56#include <polkit/polkit.h>
57
58/* Returns non zero when the client is authorized */
59unsigned IsClientAuthorized(int socket, const char* action, const char* reader)
60{
61 struct ucred cr;
62 socklen_t cr_len;
63 int ret;
64 PolkitSubject *subject;
65 PolkitAuthority *authority;
66 PolkitAuthorizationResult *result;
67 PolkitDetails *details;
68 GError *error = NULL;
69 char action_name[128];
70
71 snprintf(action_name, sizeof(action_name), "org.debian.pcsc-lite.%s", action);
72
73 cr_len = sizeof(cr);
74 ret = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
75 if (ret == -1)
76 {
77 int e = errno;
78 Log2(PCSC_LOG_CRITICAL,
79 "Error obtaining client process credentials: %s", strerror(e));
80 return 0;
81 }
82
83 authority = polkit_authority_get_sync(NULL, &error);
84 if (authority == NULL)
85 {
86 Log2(PCSC_LOG_CRITICAL, "polkit_authority_get_sync failed: %s",
87 error->message);
88 g_error_free(error);
89 return 0;
90 }
91
92 subject = polkit_unix_process_new_for_owner(cr.pid, 0, cr.uid);
93 if (subject == NULL)
94 {
95 Log1(PCSC_LOG_CRITICAL, "polkit_unix_process_new_for_owner failed");
96 ret = 0;
97 goto cleanup1;
98 }
99
100 details = polkit_details_new();
101 if (details == NULL)
102 {
103 Log1(PCSC_LOG_CRITICAL, "polkit_details_new failed");
104 ret = 0;
105 goto cleanup0;
106 }
107
108 if (reader != NULL)
109 polkit_details_insert(details, "reader", reader);
110
111 result = polkit_authority_check_authorization_sync(authority, subject,
112 action_name, details,
113 POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
114 NULL,
115 &error);
116
117 if (result == NULL)
118 {
119 Log2(PCSC_LOG_CRITICAL, "Error in authorization: %s", error->message);
120 g_error_free(error);
121 ret = 0;
122 }
123 else
124 {
125 if (polkit_authorization_result_get_is_authorized(result))
126 {
127 ret = 1;
128 }
129 else
130 {
131 ret = 0;
132 }
133 }
134
135 if (ret == 0)
136 {
137 Log4(PCSC_LOG_CRITICAL,
138 "Process %u (user: %u) is NOT authorized for action: %s",
139 (unsigned)cr.pid, (unsigned)cr.uid, action);
140 }
141
142 if (result)
143 g_object_unref(result);
144
145 g_object_unref(subject);
146cleanup0:
147 g_object_unref(details);
148cleanup1:
149 g_object_unref(authority);
150
151 return ret;
152}
153
154#else
155
156unsigned IsClientAuthorized(int socket, const char* action, const char* reader)
157{
158 (void)socket;
159 (void)action;
160 (void)reader;
161
162 return 1;
163}
164
165#endif
This handles debugging.