Update github.com git:// SRC_URIs
[AGL/meta-agl.git] / meta-app-framework / recipes-core / dbus-cynagora / dbus-cynagora / 0007-Switch-from-cynara-to-cynagora.patch
1 From 43cc361a5c32c81c0f93451bdb0ef781cd19a1cb Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Jos=C3=A9=20Bollo?= <jose.bollo@iot.bzh>
3 Date: Tue, 4 Feb 2020 12:23:36 +0100
4 Subject: [PATCH 7/8] Switch from cynara to cynagora
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
10 ---
11  bus/Makefile.am                    |   8 +-
12  bus/bus.h                          |   2 +-
13  bus/check.c                        |  26 +-
14  bus/check.h                        |   2 +-
15  bus/connection.c                   |  27 ---
16  bus/connection.h                   |   3 -
17  bus/cynagora-check.c               | 330 +++++++++++++++++++++++++
18  bus/{cynara.h => cynagora-check.h} |  10 +-
19  bus/cynara.c                       | 373 -----------------------------
20  bus/system.conf.in                 |   6 +-
21  configure.ac                       |  18 +-
22  11 files changed, 366 insertions(+), 439 deletions(-)
23  create mode 100644 bus/cynagora-check.c
24  rename bus/{cynara.h => cynagora-check.h} (81%)
25  delete mode 100644 bus/cynara.c
26
27 diff --git a/bus/Makefile.am b/bus/Makefile.am
28 index 2a8a72c..1720048 100644
29 --- a/bus/Makefile.am
30 +++ b/bus/Makefile.am
31 @@ -13,7 +13,7 @@ DBUS_BUS_LIBS = \
32         $(THREAD_LIBS) \
33         $(ADT_LIBS) \
34         $(NETWORK_libs) \
35 -       $(CYNARA_LIBS) \
36 +       $(CYNAGORA_LIBS) \
37         $(NULL)
38  
39  DBUS_LAUNCHER_LIBS = \
40 @@ -31,7 +31,7 @@ AM_CPPFLAGS = \
41         $(APPARMOR_CFLAGS) \
42         -DDBUS_SYSTEM_CONFIG_FILE=\""$(dbusdatadir)/system.conf"\" \
43         -DDBUS_COMPILATION \
44 -       $(CYNARA_CFLAGS) \
45 +       $(CYNAGORA_CFLAGS) \
46         $(NULL)
47  
48  # if assertions are enabled, improve backtraces
49 @@ -101,8 +101,8 @@ BUS_SOURCES=                                        \
50         config-parser-common.h                  \
51         connection.c                            \
52         connection.h                            \
53 -       cynara.c                                \
54 -       cynara.h                                \
55 +       cynagora-check.c                        \
56 +       cynagora-check.h                        \
57         desktop-file.c                          \
58         desktop-file.h                          \
59         $(DIR_WATCH_SOURCE)                     \
60 diff --git a/bus/bus.h b/bus/bus.h
61 index 1b08f7c..e167d9e 100644
62 --- a/bus/bus.h
63 +++ b/bus/bus.h
64 @@ -47,7 +47,7 @@ typedef struct BusMatchRule     BusMatchRule;
65  typedef struct BusActivationEntry BusActivationEntry;
66  typedef struct BusCheck         BusCheck;
67  typedef struct BusDeferredMessage BusDeferredMessage;
68 -typedef struct BusCynara        BusCynara;
69 +typedef struct BusCynagora        BusCynagora;
70  
71  /**
72   * BusResult is defined as a pointer to a dummy structure to allow detection of type mismatches.
73 diff --git a/bus/check.c b/bus/check.c
74 index b73d08b..ec30770 100644
75 --- a/bus/check.c
76 +++ b/bus/check.c
77 @@ -26,7 +26,7 @@
78  #include "check.h"
79  #include "connection.h"
80  #include "dispatch.h"
81 -#include "cynara.h"
82 +#include "cynagora-check.h"
83  #include "utils.h"
84  #include <dbus/dbus-connection-internal.h>
85  #include <dbus/dbus-message-internal.h>
86 @@ -38,7 +38,7 @@ typedef struct BusCheck
87    int refcount;
88  
89    BusContext *context;
90 -  BusCynara *cynara;
91 +  BusCynagora *cynagora;
92  } BusCheck;
93  
94  typedef struct BusDeferredMessage
95 @@ -81,7 +81,7 @@ bus_check_new (BusContext *context, DBusError *error)
96  
97    check->refcount = 1;
98    check->context = context;
99 -  check->cynara = bus_cynara_new(check, error);
100 +  check->cynagora = bus_cynagora_new(check, error);
101    if (dbus_error_is_set(error))
102      {
103        dbus_message_free_data_slot(&deferred_message_data_slot);
104 @@ -110,7 +110,7 @@ bus_check_unref (BusCheck *check)
105  
106    if (check->refcount == 0)
107      {
108 -      bus_cynara_unref(check->cynara);
109 +      bus_cynagora_unref(check->cynagora);
110        dbus_message_free_data_slot(&deferred_message_data_slot);
111        dbus_free(check);
112      }
113 @@ -122,10 +122,10 @@ bus_check_get_context (BusCheck *check)
114    return check->context;
115  }
116  
117 -BusCynara *
118 -bus_check_get_cynara (BusCheck *check)
119 +BusCynagora *
120 +bus_check_get_cynagora (BusCheck *check)
121  {
122 -  return check->cynara;
123 +  return check->cynagora;
124  }
125  
126  static void
127 @@ -276,8 +276,8 @@ bus_check_privilege (BusCheck *check,
128  {
129    BusDeferredMessage *previous_deferred_message;
130    BusResult result = BUS_RESULT_FALSE;
131 -#ifdef DBUS_ENABLE_CYNARA
132 -  BusCynara *cynara;
133 +#ifdef DBUS_ENABLE_CYNAGORA
134 +  BusCynagora *cynagora;
135  #endif
136    DBusConnection *connection;
137  
138 @@ -304,7 +304,7 @@ bus_check_privilege (BusCheck *check,
139             * Message has been deferred due to receive or own rule which means that sending this message
140             * is allowed - it must have been checked previously.
141             * This might happen when client calls RequestName method which depending on security
142 -           * policy might result in both "can_send" and "can_own" Cynara checks.
143 +           * policy might result in both "can_send" and "can_own" Cynagora checks.
144             */
145            result = BUS_RESULT_TRUE;
146          }
147 @@ -327,9 +327,9 @@ bus_check_privilege (BusCheck *check,
148    else
149      {
150        /* ask policy checkers */
151 -#ifdef DBUS_ENABLE_CYNARA
152 -      cynara = bus_check_get_cynara(check);
153 -      result = bus_cynara_check_privilege(cynara, message, sender, addressed_recipient,
154 +#ifdef DBUS_ENABLE_CYNAGORA
155 +      cynagora = bus_check_get_cynagora(check);
156 +      result = bus_cynagora_check_privilege(cynagora, message, sender, addressed_recipient,
157            proposed_recipient, privilege, check_type, deferred_message);
158  #endif
159        if (result == BUS_RESULT_LATER && deferred_message != NULL)
160 diff --git a/bus/check.h b/bus/check.h
161 index d718a69..ab63c18 100644
162 --- a/bus/check.h
163 +++ b/bus/check.h
164 @@ -45,7 +45,7 @@ BusCheck   *bus_check_ref         (BusCheck *check);
165  void        bus_check_unref       (BusCheck *check);
166  
167  BusContext *bus_check_get_context (BusCheck *check);
168 -BusCynara  *bus_check_get_cynara  (BusCheck *check);
169 +BusCynagora  *bus_check_get_cynagora  (BusCheck *check);
170  BusResult   bus_check_privilege   (BusCheck *check,
171                                     DBusMessage *message,
172                                     DBusConnection *sender,
173 diff --git a/bus/connection.c b/bus/connection.c
174 index b520d57..48910e0 100644
175 --- a/bus/connection.c
176 +++ b/bus/connection.c
177 @@ -38,10 +38,6 @@
178  #include <dbus/dbus-connection-internal.h>
179  #include <dbus/dbus-internals.h>
180  #include <dbus/dbus-message-internal.h>
181 -#ifdef DBUS_ENABLE_CYNARA
182 -#include <stdlib.h>
183 -#include <cynara-session.h>
184 -#endif
185  
186  /* Trim executed commands to this length; we want to keep logs readable */
187  #define MAX_LOG_COMMAND_LEN 50
188 @@ -124,9 +120,6 @@ typedef struct
189  
190    /** non-NULL if and only if this is a monitor */
191    DBusList *link_in_monitors;
192 -#ifdef DBUS_ENABLE_CYNARA
193 -  char *cynara_session_id;
194 -#endif
195  } BusConnectionData;
196  
197  static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
198 @@ -461,10 +454,6 @@ free_connection_data (void *data)
199    
200    dbus_free (d->name);
201    
202 -#ifdef DBUS_ENABLE_CYNARA
203 -  free (d->cynara_session_id);
204 -#endif
205 -
206    dbus_free (d);
207  }
208  
209 @@ -1095,22 +1084,6 @@ bus_connection_get_policy (DBusConnection *connection)
210    return d->policy;
211  }
212  
213 -#ifdef DBUS_ENABLE_CYNARA
214 -const char *bus_connection_get_cynara_session_id (DBusConnection *connection)
215 -{
216 -  BusConnectionData *d = BUS_CONNECTION_DATA (connection);
217 -  _dbus_assert (d != NULL);
218 -
219 -  if (d->cynara_session_id == NULL)
220 -    {
221 -      unsigned long pid;
222 -      if (dbus_connection_get_unix_process_id(connection, &pid))
223 -        d->cynara_session_id = cynara_session_from_pid(pid);
224 -    }
225 -  return d->cynara_session_id;
226 -}
227 -#endif
228 -
229  static dbus_bool_t
230  foreach_active (BusConnections               *connections,
231                  BusConnectionForeachFunction  function,
232 diff --git a/bus/connection.h b/bus/connection.h
233 index 6af7bf1..3116bcf 100644
234 --- a/bus/connection.h
235 +++ b/bus/connection.h
236 @@ -138,9 +138,6 @@ dbus_bool_t bus_connection_be_monitor (DBusConnection  *connection,
237                                         BusTransaction  *transaction,
238                                         DBusList       **rules,
239                                         DBusError       *error);
240 -#ifdef DBUS_ENABLE_CYNARA
241 -const char *bus_connection_get_cynara_session_id (DBusConnection *connection);
242 -#endif
243  
244  /* transaction API so we can send or not send a block of messages as a whole */
245  
246 diff --git a/bus/cynagora-check.c b/bus/cynagora-check.c
247 new file mode 100644
248 index 0000000..6c0c635
249 --- /dev/null
250 +++ b/bus/cynagora-check.c
251 @@ -0,0 +1,330 @@
252 +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
253 +/* cynagora.c  Cynagora runtime privilege checking
254 + *
255 + * Copyright (c) 2014 Samsung Electronics, Ltd.
256 + *
257 + * Licensed under the Academic Free License version 2.1
258 + *
259 + * This program is free software; you can redistribute it and/or modify
260 + * it under the terms of the GNU General Public License as published by
261 + * the Free Software Foundation; either version 2 of the License, or
262 + * (at your option) any later version.
263 + *
264 + * This program is distributed in the hope that it will be useful,
265 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
266 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
267 + * GNU General Public License for more details.
268 + *
269 + * You should have received a copy of the GNU General Public License
270 + * along with this program; if not, write to the Free Software
271 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
272 + *
273 + */
274 +
275 +#include <config.h>
276 +#include "cynagora-check.h"
277 +#include "check.h"
278 +#include "utils.h"
279 +
280 +#include <stdlib.h>
281 +#include <stdio.h>
282 +#include <errno.h>
283 +
284 +#include <dbus/dbus.h>
285 +#include <dbus/dbus-watch.h>
286 +#include <dbus/dbus-connection-internal.h>
287 +#include <bus/connection.h>
288 +
289 +#ifndef DBUS_ENABLE_CYNAGORA
290 +
291 +BusCynagora *
292 +bus_cynagora_new(BusCheck *check, DBusError *error)
293 +{
294 +  return NULL;
295 +}
296 +
297 +BusCynagora *
298 +bus_cynagora_ref (BusCynagora *cynagora)
299 +{
300 +  return NULL;
301 +}
302 +
303 +void
304 +bus_cynagora_unref (BusCynagora *cynagora)
305 +{
306 +}
307 +
308 +BusResult
309 +bus_cynagora_check_privilege (BusCynagora *cynagora,
310 +                            DBusMessage *message,
311 +                            DBusConnection *sender,
312 +                            DBusConnection *addressed_recipient,
313 +                            DBusConnection *proposed_recipient,
314 +                            const char *privilege,
315 +                            BusDeferredMessageStatus check_type,
316 +                            BusDeferredMessage **deferred_message_param)
317 +{
318 +  return BUS_RESULT_FALSE;
319 +}
320 +
321 +#endif
322 +
323 +#ifdef DBUS_ENABLE_CYNAGORA
324 +
325 +#include <time.h>
326 +#include <sys/epoll.h>
327 +
328 +#include <cynagora.h>
329 +
330 +#ifndef CYNAGORA_CACHE_SIZE
331 +#define CYNAGORA_CACHE_SIZE 8000
332 +#endif
333 +
334 +typedef struct BusCynagora
335 +{
336 +  int refcount;
337 +
338 +  BusContext   *context;
339 +  BusCheck     *check;
340 +  cynagora_t   *cynagora;
341 +  DBusWatch    *cynagora_watch;
342 +} BusCynagora;
343 +
344 +static int async_callback(void *closure,
345 +                          int op,
346 +                          int fd,
347 +                          uint32_t events);
348 +
349 +BusCynagora *
350 +bus_cynagora_new(BusCheck *check, DBusError *error)
351 +{
352 +  BusContext *context;
353 +  BusCynagora *cynagora;
354 +  int ret;
355 +
356 +  cynagora = dbus_new(BusCynagora, 1);
357 +  if (cynagora == NULL)
358 +    {
359 +      BUS_SET_OOM(error);
360 +      return NULL;
361 +    }
362 +
363 +  context = bus_check_get_context(check);
364 +
365 +  cynagora->refcount = 1;
366 +  cynagora->check = check;
367 +  cynagora->context = context;
368 +  cynagora->cynagora_watch = NULL;
369 +
370 +  ret = cynagora_create(&cynagora->cynagora, cynagora_Check, CYNAGORA_CACHE_SIZE, NULL);
371 +  if (ret < 0)
372 +    {
373 +      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to create Cynagora configuration");
374 +    }
375 +  else
376 +    {
377 +      ret = cynagora_async_setup(cynagora->cynagora, async_callback, cynagora);
378 +      if (ret < 0)
379 +        {
380 +          dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to initialize Cynagora client");
381 +        }
382 +        else
383 +        {
384 +          return cynagora;
385 +        }
386 +        cynagora_destroy(cynagora->cynagora);
387 +    }
388 +
389 +  dbus_free(cynagora);
390 +  return NULL;
391 +}
392 +
393 +BusCynagora *
394 +bus_cynagora_ref (BusCynagora *cynagora)
395 +{
396 +  _dbus_assert (cynagora->refcount > 0);
397 +  cynagora->refcount += 1;
398 +
399 +  return cynagora;
400 +}
401 +
402 +void
403 +bus_cynagora_unref (BusCynagora *cynagora)
404 +{
405 +  _dbus_assert (cynagora->refcount > 0);
406 +
407 +  cynagora->refcount -= 1;
408 +
409 +  if (cynagora->refcount == 0)
410 +    {
411 +      cynagora_destroy(cynagora->cynagora);
412 +      dbus_free(cynagora);
413 +    }
414 +}
415 +
416 +static void
417 +async_check_callback (void *closure, int status)
418 +{
419 +  BusDeferredMessage *deferred_message = closure;
420 +  BusResult result;
421 +
422 +  if (deferred_message == NULL)
423 +    return;
424 +
425 +  if (status == 1)
426 +    result = BUS_RESULT_TRUE;
427 +  else
428 +    result = BUS_RESULT_FALSE;
429 +
430 +  bus_deferred_message_response_received(deferred_message, result);
431 +  bus_deferred_message_unref(deferred_message);
432 +}
433 +
434 +BusResult
435 +bus_cynagora_check_privilege (BusCynagora *cynagora,
436 +                            DBusMessage *message,
437 +                            DBusConnection *sender,
438 +                            DBusConnection *addressed_recipient,
439 +                            DBusConnection *proposed_recipient,
440 +                            const char *permission,
441 +                            BusDeferredMessageStatus check_type,
442 +                            BusDeferredMessage **deferred_message_param)
443 +{
444 +  int result;
445 +  unsigned long uid;
446 +  unsigned long pid;
447 +  char *label;
448 +  char user[32];
449 +  char session[32];
450 +  DBusConnection *connection = check_type == BUS_DEFERRED_MESSAGE_CHECK_RECEIVE ? proposed_recipient : sender;
451 +  BusDeferredMessage *deferred_message;
452 +  BusResult ret;
453 +  cynagora_key_t key;
454 +
455 +  _dbus_assert(connection != NULL);
456 +
457 +  if (dbus_connection_get_unix_user(connection, &uid) == FALSE)
458 +      return BUS_RESULT_FALSE;
459 +
460 +  if (dbus_connection_get_unix_process_id(connection, &pid) == FALSE)
461 +      return BUS_RESULT_FALSE;
462 +
463 +  if (_dbus_connection_get_linux_security_label(connection, &label) == FALSE || label == NULL)
464 +    {
465 +      _dbus_warn("Failed to obtain security label for connection\n");
466 +      return BUS_RESULT_FALSE;
467 +    }
468 +
469 +  snprintf(user, sizeof(user), "%lu", uid);
470 +  snprintf(session, sizeof(session), "%lu", pid);
471 +
472 +  key.client = label;
473 +  key.session = session;
474 +  key.user = user;
475 +  key.permission = permission;
476 +
477 +  result = cynagora_cache_check(cynagora->cynagora, &key);
478 +  switch (result)
479 +  {
480 +  case 1:
481 +    _dbus_verbose("Cynagora: got ALLOWED answer from cache (client=%s session_id=%s user=%s permission=%s)\n",
482 +               label, session_id, user, permission);
483 +    ret = BUS_RESULT_TRUE;
484 +    break;
485 +
486 +  case 0:
487 +    _dbus_verbose("Cynagora: got DENIED answer from cache (client=%s session_id=%s user=%s permission=%s)\n",
488 +               label, session_id, user, permission);
489 +    ret = BUS_RESULT_FALSE;
490 +    break;
491 +
492 +  default:
493 +     deferred_message = bus_deferred_message_new(message, sender, addressed_recipient,
494 +         proposed_recipient, BUS_RESULT_LATER);
495 +     if (deferred_message == NULL)
496 +       {
497 +         _dbus_verbose("Failed to allocate memory for deferred message\n");
498 +         ret = BUS_RESULT_FALSE;
499 +         goto out;
500 +       }
501 +
502 +    /* callback is supposed to unref deferred_message*/
503 +    result = cynagora_async_check(cynagora->cynagora, &key, 1, 0, async_check_callback, deferred_message);
504 +    if (result == 0)
505 +      {
506 +        _dbus_verbose("Created Cynagora request: client=%s session_id=%s user=%s permission=%s "
507 +            "deferred_message=%p\n", label, session_id, user, permission, deferred_message);
508 +        if (deferred_message_param != NULL)
509 +          *deferred_message_param = deferred_message;
510 +        ret = BUS_RESULT_LATER;
511 +      }
512 +    else
513 +      {
514 +        _dbus_verbose("Error on cynagora request create: %i\n", result);
515 +        bus_deferred_message_unref(deferred_message);
516 +        ret = BUS_RESULT_FALSE;
517 +      }
518 +    break;
519 +  }
520 +out:
521 +  dbus_free(label);
522 +  return ret;
523 +}
524 +
525 +static dbus_bool_t
526 +watch_handler_callback(DBusWatch    *watch,
527 +                       unsigned int  flags,
528 +                       void         *data)
529 +{
530 +  BusCynagora *cynagora = (BusCynagora *)data;
531 +  int result = cynagora_async_process(cynagora->cynagora);
532 +  if (result < 0)
533 +      _dbus_verbose("cynagora_async_process returned %d\n", result);
534 +
535 +  return result != -ENOMEM ? TRUE : FALSE;
536 +}
537 +
538 +static int
539 +async_callback(void *closure, int op, int fd, uint32_t events)
540 +{
541 +  BusCynagora *cynagora = (BusCynagora *)closure;
542 +  DBusLoop *loop = bus_context_get_loop(cynagora->context);
543 +  unsigned int flags;
544 +  DBusWatch *watch;
545 +
546 +  /* compute flags */
547 +  flags = 0;
548 +  if (events & EPOLLIN)
549 +    flags |= DBUS_WATCH_READABLE;
550 +  if (events & EPOLLOUT)
551 +    flags |= DBUS_WATCH_WRITABLE;
552 +
553 +  /* remove the watch if needed */
554 +  watch = cynagora->cynagora_watch;
555 +  if (watch != NULL)
556 +    {
557 +      cynagora->cynagora_watch = NULL;
558 +      _dbus_loop_remove_watch(loop, watch);
559 +      _dbus_watch_invalidate(watch);
560 +      _dbus_watch_unref(watch);
561 +    }
562 +
563 +  /* create the watch if needed */
564 +  watch = cynagora->cynagora_watch;
565 +  if (op != EPOLL_CTL_DEL)
566 +    {
567 +      watch = _dbus_watch_new(fd, flags, TRUE, watch_handler_callback, cynagora, NULL);
568 +      if (watch == NULL)
569 +        return -ENOMEM;
570 +      if (_dbus_loop_add_watch(loop, watch) != TRUE)
571 +        {
572 +          _dbus_watch_invalidate(watch);
573 +          _dbus_watch_unref(watch);
574 +          return -ENOMEM;
575 +        }
576 +      cynagora->cynagora_watch = watch;
577 +    }
578 +  return 0;
579 +}
580 +
581 +#endif /* DBUS_ENABLE_CYNAGORA */
582 diff --git a/bus/cynara.h b/bus/cynagora-check.h
583 similarity index 81%
584 rename from bus/cynara.h
585 rename to bus/cynagora-check.h
586 index c4728bb..c0892c3 100644
587 --- a/bus/cynara.h
588 +++ b/bus/cynagora-check.h
589 @@ -1,5 +1,5 @@
590  /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
591 -/* cynara.h  Cynara runtime privilege checking
592 +/* cynagora.h  Cynagora runtime privilege checking
593   *
594   * Copyright (c) 2014 Samsung Electronics, Ltd.
595   *
596 @@ -24,10 +24,10 @@
597  #include "bus.h"
598  #include "check.h"
599  
600 -BusCynara *bus_cynara_new             (BusCheck *check, DBusError *error);
601 -BusCynara *bus_cynara_ref             (BusCynara *cynara);
602 -void       bus_cynara_unref           (BusCynara *cynara);
603 -BusResult  bus_cynara_check_privilege (BusCynara *cynara,
604 +BusCynagora *bus_cynagora_new             (BusCheck *check, DBusError *error);
605 +BusCynagora *bus_cynagora_ref             (BusCynagora *cynagora);
606 +void       bus_cynagora_unref           (BusCynagora *cynagora);
607 +BusResult  bus_cynagora_check_privilege (BusCynagora *cynagora,
608                                         DBusMessage *message,
609                                         DBusConnection *sender,
610                                         DBusConnection *addressed_recipient,
611 diff --git a/bus/cynara.c b/bus/cynara.c
612 deleted file mode 100644
613 index 77aed62..0000000
614 --- a/bus/cynara.c
615 +++ /dev/null
616 @@ -1,373 +0,0 @@
617 -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
618 -/* cynara.c  Cynara runtime privilege checking
619 - *
620 - * Copyright (c) 2014 Samsung Electronics, Ltd.
621 - *
622 - * Licensed under the Academic Free License version 2.1
623 - *
624 - * This program is free software; you can redistribute it and/or modify
625 - * it under the terms of the GNU General Public License as published by
626 - * the Free Software Foundation; either version 2 of the License, or
627 - * (at your option) any later version.
628 - *
629 - * This program is distributed in the hope that it will be useful,
630 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
631 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
632 - * GNU General Public License for more details.
633 - *
634 - * You should have received a copy of the GNU General Public License
635 - * along with this program; if not, write to the Free Software
636 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
637 - *
638 - */
639 -
640 -#include <config.h>
641 -#include "cynara.h"
642 -#include "check.h"
643 -#include "utils.h"
644 -
645 -#include <stdio.h>
646 -
647 -#include <dbus/dbus.h>
648 -#include <dbus/dbus-watch.h>
649 -#include <dbus/dbus-connection-internal.h>
650 -#include <bus/connection.h>
651 -#ifdef DBUS_ENABLE_CYNARA
652 -#include <cynara-client-async.h>
653 -#endif
654 -
655 -#ifdef DBUS_ENABLE_CYNARA
656 -typedef struct BusCynara
657 -{
658 -  int refcount;
659 -
660 -  BusContext   *context;
661 -  BusCheck     *check;
662 -  cynara_async *cynara;
663 -  DBusWatch    *cynara_watch;
664 -} BusCynara;
665 -
666 -#define USE_CYNARA_CACHE 1
667 -#ifdef USE_CYNARA_CACHE
668 -#define CYNARA_CACHE_SIZE 1000
669 -#endif
670 -
671 -static dbus_bool_t bus_cynara_watch_callback(DBusWatch *watch,
672 -                                             unsigned int flags,
673 -                                             void *data);
674 -
675 -static void status_callback(int old_fd,
676 -                            int new_fd,
677 -                            cynara_async_status status,
678 -                            void *user_status_data);
679 -static void bus_cynara_check_response_callback (cynara_check_id check_id,
680 -                                                cynara_async_call_cause cause,
681 -                                                int response,
682 -                                                void *user_response_data);
683 -#endif
684 -
685 -
686 -BusCynara *
687 -bus_cynara_new(BusCheck *check, DBusError *error)
688 -{
689 -#ifdef DBUS_ENABLE_CYNARA
690 -  BusContext *context;
691 -  BusCynara *cynara;
692 -  cynara_async_configuration *conf = NULL;
693 -  int ret;
694 -
695 -  cynara = dbus_new(BusCynara, 1);
696 -  if (cynara == NULL)
697 -    {
698 -      BUS_SET_OOM(error);
699 -      return NULL;
700 -    }
701 -
702 -  context = bus_check_get_context(check);
703 -
704 -  cynara->refcount = 1;
705 -  cynara->check = check;
706 -  cynara->context = context;
707 -  cynara->cynara_watch = NULL;
708 -
709 -  ret = cynara_async_configuration_create(&conf);
710 -  if (ret != CYNARA_API_SUCCESS)
711 -    {
712 -      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to create Cynara configuration");
713 -      goto out;
714 -    }
715 -
716 -#ifdef CYNARA_CACHE_SIZE
717 -  ret = cynara_async_configuration_set_cache_size(conf, CYNARA_CACHE_SIZE);
718 -  if (ret != CYNARA_API_SUCCESS)
719 -    {
720 -      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to Cynara cache size");
721 -      goto out;
722 -    }
723 -#endif
724 -
725 -  ret = cynara_async_initialize(&cynara->cynara, conf, &status_callback, cynara);
726 -  if (ret != CYNARA_API_SUCCESS)
727 -    {
728 -      dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to initialize Cynara client");
729 -      goto out;
730 -    }
731 -
732 -out:
733 -  cynara_async_configuration_destroy(conf);
734 -  if (ret != CYNARA_API_SUCCESS)
735 -    {
736 -      dbus_free(cynara);
737 -      return NULL;
738 -    }
739 -
740 -  return cynara;
741 -#else
742 -  return NULL;
743 -#endif
744 -}
745 -
746 -BusCynara *
747 -bus_cynara_ref (BusCynara *cynara)
748 -{
749 -#ifdef DBUS_ENABLE_CYNARA
750 -  _dbus_assert (cynara->refcount > 0);
751 -  cynara->refcount += 1;
752 -
753 -  return cynara;
754 -#else
755 -  return NULL;
756 -#endif
757 -}
758 -
759 -void
760 -bus_cynara_unref (BusCynara *cynara)
761 -{
762 -#ifdef DBUS_ENABLE_CYNARA
763 -  _dbus_assert (cynara->refcount > 0);
764 -
765 -  cynara->refcount -= 1;
766 -
767 -  if (cynara->refcount == 0)
768 -    {
769 -      cynara_async_finish(cynara->cynara);
770 -      dbus_free(cynara);
771 -    }
772 -#endif
773 -}
774 -
775 -BusResult
776 -bus_cynara_check_privilege (BusCynara *cynara,
777 -                            DBusMessage *message,
778 -                            DBusConnection *sender,
779 -                            DBusConnection *addressed_recipient,
780 -                            DBusConnection *proposed_recipient,
781 -                            const char *privilege,
782 -                            BusDeferredMessageStatus check_type,
783 -                            BusDeferredMessage **deferred_message_param)
784 -{
785 -#ifdef DBUS_ENABLE_CYNARA
786 -  int result;
787 -  unsigned long uid;
788 -  char *label;
789 -  const char *session_id;
790 -  char user[32];
791 -  cynara_check_id check_id;
792 -  DBusConnection *connection = check_type == BUS_DEFERRED_MESSAGE_CHECK_RECEIVE ? proposed_recipient : sender;
793 -  BusDeferredMessage *deferred_message;
794 -  BusResult ret;
795 -
796 -  _dbus_assert(connection != NULL);
797 -
798 -  if (dbus_connection_get_unix_user(connection, &uid) == FALSE)
799 -      return BUS_RESULT_FALSE;
800 -
801 -  if (_dbus_connection_get_linux_security_label(connection, &label) == FALSE || label == NULL)
802 -    {
803 -      _dbus_warn("Failed to obtain security label for connection\n");
804 -      return BUS_RESULT_FALSE;
805 -    }
806 -
807 -  session_id = bus_connection_get_cynara_session_id (connection);
808 -  if (session_id == NULL)
809 -    {
810 -      ret = BUS_RESULT_FALSE;
811 -      goto out;
812 -    }
813 -
814 -  snprintf(user, sizeof(user), "%lu", uid);
815 -
816 -#if USE_CYNARA_CACHE
817 -  result = cynara_async_check_cache(cynara->cynara, label, session_id, user, privilege);
818 -#else
819 -  result = CYNARA_API_CACHE_MISS;
820 -#endif
821 -
822 -  switch (result)
823 -  {
824 -  case CYNARA_API_ACCESS_ALLOWED:
825 -    _dbus_verbose("Cynara: got ALLOWED answer from cache (client=%s session_id=%s user=%s privilege=%s)\n",
826 -               label, session_id, user, privilege);
827 -    ret = BUS_RESULT_TRUE;
828 -    break;
829 -
830 -  case CYNARA_API_ACCESS_DENIED:
831 -    _dbus_verbose("Cynara: got DENIED answer from cache (client=%s session_id=%s user=%s privilege=%s)\n",
832 -               label, session_id, user, privilege);
833 -    ret = BUS_RESULT_FALSE;
834 -    break;
835 -
836 -  case CYNARA_API_CACHE_MISS:
837 -     deferred_message = bus_deferred_message_new(message, sender, addressed_recipient,
838 -         proposed_recipient, BUS_RESULT_LATER);
839 -     if (deferred_message == NULL)
840 -       {
841 -         _dbus_verbose("Failed to allocate memory for deferred message\n");
842 -         ret = BUS_RESULT_FALSE;
843 -         goto out;
844 -       }
845 -
846 -    /* callback is supposed to unref deferred_message*/
847 -    result = cynara_async_create_request(cynara->cynara, label, session_id, user, privilege, &check_id,
848 -        &bus_cynara_check_response_callback, deferred_message);
849 -    if (result == CYNARA_API_SUCCESS)
850 -      {
851 -        _dbus_verbose("Created Cynara request: client=%s session_id=%s user=%s privilege=%s check_id=%u "
852 -            "deferred_message=%p\n", label, session_id, user, privilege, (unsigned int)check_id, deferred_message);
853 -        if (deferred_message_param != NULL)
854 -          *deferred_message_param = deferred_message;
855 -        ret = BUS_RESULT_LATER;
856 -      }
857 -    else
858 -      {
859 -        _dbus_verbose("Error on cynara request create: %i\n", result);
860 -        bus_deferred_message_unref(deferred_message);
861 -        ret = BUS_RESULT_FALSE;
862 -      }
863 -    break;
864 -  default:
865 -    _dbus_verbose("Error when accessing Cynara cache: %i\n", result);
866 -    ret = BUS_RESULT_FALSE;
867 -  }
868 -out:
869 -  dbus_free(label);
870 -  return ret;
871 -
872 -#else
873 -  return BUS_RESULT_FALSE;
874 -#endif
875 -}
876 -
877 -
878 -
879 -#ifdef DBUS_ENABLE_CYNARA
880 -static void
881 -status_callback(int old_fd, int new_fd, cynara_async_status status,
882 -                void *user_status_data)
883 -{
884 -  BusCynara *cynara = (BusCynara *)user_status_data;
885 -  DBusLoop *loop = bus_context_get_loop(cynara->context);
886 -
887 -  if (cynara->cynara_watch != NULL)
888 -    {
889 -      _dbus_loop_remove_watch(loop, cynara->cynara_watch);
890 -      _dbus_watch_invalidate(cynara->cynara_watch);
891 -      _dbus_watch_unref(cynara->cynara_watch);
892 -      cynara->cynara_watch = NULL;
893 -    }
894 -
895 -  if (new_fd != -1)
896 -    {
897 -      unsigned int flags;
898 -      DBusWatch *watch;
899 -
900 -      switch (status)
901 -      {
902 -      case CYNARA_STATUS_FOR_READ:
903 -        flags = DBUS_WATCH_READABLE;
904 -        break;
905 -      case CYNARA_STATUS_FOR_RW:
906 -        flags = DBUS_WATCH_READABLE | DBUS_WATCH_WRITABLE;
907 -        break;
908 -      default:
909 -        /* Cynara passed unknown status - warn and add RW watch */
910 -        _dbus_verbose("Cynara passed unknown status value: 0x%08X\n", (unsigned int)status);
911 -        flags = DBUS_WATCH_READABLE | DBUS_WATCH_WRITABLE;
912 -        break;
913 -      }
914 -
915 -      watch = _dbus_watch_new(new_fd, flags, TRUE, &bus_cynara_watch_callback, cynara, NULL);
916 -      if (watch != NULL)
917 -        {
918 -          if (_dbus_loop_add_watch(loop, watch) == TRUE)
919 -            {
920 -              cynara->cynara_watch = watch;
921 -              return;
922 -            }
923 -
924 -          _dbus_watch_invalidate(watch);
925 -          _dbus_watch_unref(watch);
926 -        }
927 -
928 -      /* It seems like not much can be done at this point. Cynara events won't be processed
929 -       * until next Cynara function call triggering status callback */
930 -      _dbus_verbose("Failed to add dbus watch\n");
931 -    }
932 -}
933 -
934 -static dbus_bool_t
935 -bus_cynara_watch_callback(DBusWatch    *watch,
936 -                          unsigned int  flags,
937 -                          void         *data)
938 -{
939 -  BusCynara *cynara = (BusCynara *)data;
940 -  int result = cynara_async_process(cynara->cynara);
941 -  if (result != CYNARA_API_SUCCESS)
942 -      _dbus_verbose("cynara_async_process returned %d\n", result);
943 -
944 -  return result != CYNARA_API_OUT_OF_MEMORY ? TRUE : FALSE;
945 -}
946 -
947 -static inline const char *
948 -call_cause_to_string(cynara_async_call_cause cause)
949 -{
950 -  switch (cause)
951 -  {
952 -  case CYNARA_CALL_CAUSE_ANSWER:
953 -    return "ANSWER";
954 -  case CYNARA_CALL_CAUSE_CANCEL:
955 -    return "CANCEL";
956 -  case CYNARA_CALL_CAUSE_FINISH:
957 -    return "FINSIH";
958 -  case CYNARA_CALL_CAUSE_SERVICE_NOT_AVAILABLE:
959 -    return "SERVICE NOT AVAILABLE";
960 -  default:
961 -    return "INVALID";
962 -  }
963 -}
964 -
965 -static void
966 -bus_cynara_check_response_callback (cynara_check_id check_id,
967 -                                    cynara_async_call_cause cause,
968 -                                    int response,
969 -                                    void *user_response_data)
970 -{
971 -  BusDeferredMessage *deferred_message = user_response_data;
972 -  BusResult result;
973 -
974 -  _dbus_verbose("Cynara callback: check_id=%u, cause=%s response=%i response_data=%p\n",
975 -      (unsigned int)check_id, call_cause_to_string(cause), response, user_response_data);
976 -
977 -  if (deferred_message == NULL)
978 -    return;
979 -
980 -  if (cause == CYNARA_CALL_CAUSE_ANSWER && response == CYNARA_API_ACCESS_ALLOWED)
981 -    result = BUS_RESULT_TRUE;
982 -  else
983 -    result = BUS_RESULT_FALSE;
984 -
985 -  bus_deferred_message_response_received(deferred_message, result);
986 -  bus_deferred_message_unref(deferred_message);
987 -}
988 -
989 -#endif /* DBUS_ENABLE_CYNARA */
990 diff --git a/bus/system.conf.in b/bus/system.conf.in
991 index 19d0c04..81c39c8 100644
992 --- a/bus/system.conf.in
993 +++ b/bus/system.conf.in
994 @@ -72,10 +72,10 @@
995             send_interface="org.freedesktop.DBus.Introspectable"/>
996      <allow send_destination="org.freedesktop.DBus"
997             send_interface="org.freedesktop.DBus.Properties"/>
998 -    <!-- If there is a need specific bus services could be protected by Cynara as well.
999 +    <!-- If there is a need specific bus services could be protected by Cynagora as well.
1000           However, this can lead to deadlock during the boot process when such check is made and
1001 -         Cynara is not yet activated (systemd calls protected method synchronously,
1002 -         dbus daemon tries to consult Cynara, Cynara waits for systemd activation).
1003 +         Cynagora is not yet activated (systemd calls protected method synchronously,
1004 +         dbus daemon tries to consult Cynagora, Cynagora waits for systemd activation).
1005           Therefore it is advised to allow root processes to use bus services.
1006           Currently anyone is allowed to talk to the message bus -->
1007      <allow receive_sender="org.freedesktop.DBus"/>
1008 diff --git a/configure.ac b/configure.ac
1009 index 11b5ffd..df9341c 100644
1010 --- a/configure.ac
1011 +++ b/configure.ac
1012 @@ -1742,16 +1742,16 @@ AC_ARG_ENABLE([user-session],
1013  AM_CONDITIONAL([DBUS_ENABLE_USER_SESSION],
1014    [test "x$enable_user_session" = xyes])
1015  
1016 -#enable cynara integration
1017 -AC_ARG_ENABLE([cynara], [AS_HELP_STRING([--enable-cynara], [enable Cynara integration])], [], [enable_cynara=no])
1018 -if test "x$enable_cynara" = xyes; then
1019 -  PKG_CHECK_MODULES([CYNARA], [cynara-client-async >= 0.6.0 cynara-session >= 0.6.0],
1020 -     [AC_DEFINE([DBUS_ENABLE_CYNARA], [1], [Define to enable Cynara privilege checks in dbus-daemon])],
1021 -     [AC_MSG_ERROR([libcynara-client-async and cynara-session are required to enable Cynara integration])])
1022 +#enable cynagora integration
1023 +AC_ARG_ENABLE([cynagora], [AS_HELP_STRING([--enable-cynagora], [enable Cynagora integration])], [], [enable_cynagora=no])
1024 +if test "x$enable_cynagora" = xyes; then
1025 +  PKG_CHECK_MODULES([CYNAGORA], [cynagora],
1026 +     [AC_DEFINE([DBUS_ENABLE_CYNAGORA], [1], [Define to enable Cynagora privilege checks in dbus-daemon])],
1027 +     [AC_MSG_ERROR([libcynagora is required to enable Cynagora integration])])
1028  fi
1029  
1030 -AC_SUBST([CYNARA_CFLAGS])
1031 -AC_SUBST([CYNARA_LIBS])
1032 +AC_SUBST([CYNAGORA_CFLAGS])
1033 +AC_SUBST([CYNAGORA_LIBS])
1034  
1035  AC_CONFIG_FILES([
1036  Doxyfile
1037 @@ -1835,7 +1835,7 @@ echo "
1038          Building bus stats API:   ${enable_stats}
1039          Building SELinux support: ${have_selinux}
1040          Building AppArmor support: ${have_apparmor}
1041 -        Building Cynara support:  ${enable_cynara}
1042 +        Building Cynagora support: ${enable_cynagora}
1043          Building inotify support: ${have_inotify}
1044          Building kqueue support:  ${have_kqueue}
1045          Building systemd support: ${have_systemd}
1046 -- 
1047 2.21.1
1048