pcsc-lite  2.2.3
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 
59 extern bool disable_polkit;
60 
61 /* Returns non zero when the client is authorized */
62 unsigned 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);
154 cleanup0:
155  g_object_unref(details);
156 cleanup1:
157  g_object_unref(authority);
158 
159  return ret;
160 }
161 
162 #else
163 
164 unsigned 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
debuglog.h
This handles debugging.