pcsc-lite 1.9.9
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#include <stdbool.h>
58
59extern bool disable_polkit;
60
61/* Returns non zero when the client is authorized */
62unsigned IsClientAuthorized(int socket, const char* action, const char* reader)
63{
64 struct ucred cr;
65 socklen_t cr_len;
66 int ret;
67 PolkitSubject *subject;
68 PolkitAuthority *authority;
69 PolkitAuthorizationResult *result;
70 PolkitDetails *details;
71 GError *error = NULL;
72 char action_name[128];
73
74 if (disable_polkit)
75 return 1;
76
77 snprintf(action_name, sizeof(action_name), "org.debian.pcsc-lite.%s", action);
78
79 cr_len = sizeof(cr);
80 ret = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
81 if (ret == -1)
82 {
83 int e = errno;
84 Log2(PCSC_LOG_CRITICAL,
85 "Error obtaining client process credentials: %s", strerror(e));
86 return 0;
87 }
88
89 authority = polkit_authority_get_sync(NULL, &error);
90 if (authority == NULL)
91 {
92 Log2(PCSC_LOG_CRITICAL, "polkit_authority_get_sync failed: %s",
93 error->message);
94 g_error_free(error);
95 return 0;
96 }
97
98 subject = polkit_unix_process_new_for_owner(cr.pid, 0, cr.uid);
99 if (subject == NULL)
100 {
101 Log1(PCSC_LOG_CRITICAL, "polkit_unix_process_new_for_owner failed");
102 ret = 0;
103 goto cleanup1;
104 }
105
106 details = polkit_details_new();
107 if (details == NULL)
108 {
109 Log1(PCSC_LOG_CRITICAL, "polkit_details_new failed");
110 ret = 0;
111 goto cleanup0;
112 }
113
114 if (reader != NULL)
115 polkit_details_insert(details, "reader", reader);
116
117 result = polkit_authority_check_authorization_sync(authority, subject,
118 action_name, details,
119 POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
120 NULL,
121 &error);
122
123 if (result == NULL)
124 {
125 Log2(PCSC_LOG_CRITICAL, "Error in authorization: %s", error->message);
126 g_error_free(error);
127 ret = 0;
128 }
129 else
130 {
131 if (polkit_authorization_result_get_is_authorized(result))
132 {
133 ret = 1;
134 }
135 else
136 {
137 ret = 0;
138 }
139 }
140
141 if (ret == 0)
142 {
143 Log4(PCSC_LOG_CRITICAL,
144 "Process %u (user: %u) is NOT authorized for action: %s",
145 (unsigned)cr.pid, (unsigned)cr.uid, action);
146 }
147
148 if (result)
149 g_object_unref(result);
150
151 g_object_unref(subject);
152cleanup0:
153 g_object_unref(details);
154cleanup1:
155 g_object_unref(authority);
156
157 return ret;
158}
159
160#else
161
162unsigned IsClientAuthorized(int socket, const char* action, const char* reader)
163{
164 (void)socket;
165 (void)action;
166 (void)reader;
167
168 return 1;
169}
170
171#endif
This handles debugging.