pcsc-lite 2.3.0
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#ifndef NO_LOG
84 int e = errno;
85 Log2(PCSC_LOG_CRITICAL,
86 "Error obtaining client process credentials: %s", strerror(e));
87#endif
88 return 0;
89 }
90
91 authority = polkit_authority_get_sync(NULL, &error);
92 if (authority == NULL)
93 {
94 Log2(PCSC_LOG_CRITICAL, "polkit_authority_get_sync failed: %s",
95 error->message);
96 g_error_free(error);
97 return 0;
98 }
99
100 subject = polkit_unix_process_new_for_owner(cr.pid, 0, cr.uid);
101 if (subject == NULL)
102 {
103 Log1(PCSC_LOG_CRITICAL, "polkit_unix_process_new_for_owner failed");
104 ret = 0;
105 goto cleanup1;
106 }
107
108 details = polkit_details_new();
109 if (details == NULL)
110 {
111 Log1(PCSC_LOG_CRITICAL, "polkit_details_new failed");
112 ret = 0;
113 goto cleanup0;
114 }
115
116 if (reader != NULL)
117 polkit_details_insert(details, "reader", reader);
118
119 result = polkit_authority_check_authorization_sync(authority, subject,
120 action_name, details,
121 POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
122 NULL,
123 &error);
124
125 if (result == NULL)
126 {
127 Log2(PCSC_LOG_CRITICAL, "Error in authorization: %s", error->message);
128 g_error_free(error);
129 ret = 0;
130 }
131 else
132 {
133 if (polkit_authorization_result_get_is_authorized(result))
134 {
135 ret = 1;
136 }
137 else
138 {
139 ret = 0;
140 }
141 }
142
143 if (ret == 0)
144 {
145 Log4(PCSC_LOG_CRITICAL,
146 "Process %u (user: %u) is NOT authorized for action: %s",
147 (unsigned)cr.pid, (unsigned)cr.uid, action);
148 }
149
150 if (result)
151 g_object_unref(result);
152
153 g_object_unref(subject);
154cleanup0:
155 g_object_unref(details);
156cleanup1:
157 g_object_unref(authority);
158
159 return ret;
160}
161
162#else
163
164unsigned IsClientAuthorized(int socket, const char* action, const char* reader)
165{
166 (void)socket;
167 (void)action;
168 (void)reader;
169
170 return 1;
171}
172
173#endif
This handles debugging.