chiark / gitweb /
bus-proxy: share policy between threads
[elogind.git] / src / bus-proxyd / proxy.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2013 Daniel Mack
8   Copyright 2014 Kay Sievers
9   Copyright 2014 David Herrmann
10
11   systemd is free software; you can redistribute it and/or modify it
12   under the terms of the GNU Lesser General Public License as published by
13   the Free Software Foundation; either version 2.1 of the License, or
14   (at your option) any later version.
15
16   systemd is distributed in the hope that it will be useful, but
17   WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19   Lesser General Public License for more details.
20
21   You should have received a copy of the GNU Lesser General Public License
22   along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 ***/
24
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <sys/poll.h>
33 #include <stddef.h>
34 #include <getopt.h>
35
36 #include "log.h"
37 #include "util.h"
38 #include "socket-util.h"
39 #include "sd-daemon.h"
40 #include "sd-bus.h"
41 #include "bus-internal.h"
42 #include "bus-message.h"
43 #include "bus-util.h"
44 #include "build.h"
45 #include "strv.h"
46 #include "def.h"
47 #include "capability.h"
48 #include "bus-control.h"
49 #include "smack-util.h"
50 #include "set.h"
51 #include "bus-xml-policy.h"
52 #include "driver.h"
53 #include "proxy.h"
54 #include "synthesize.h"
55
56 static int proxy_create_dest(Proxy *p, const char *dest, const char *local_sec, bool negotiate_fds) {
57         _cleanup_bus_close_unref_ sd_bus *b = NULL;
58         int r;
59
60         r = sd_bus_new(&b);
61         if (r < 0)
62                 return log_error_errno(r, "Failed to allocate bus: %m");
63
64         r = sd_bus_set_description(b, "sd-proxy");
65         if (r < 0)
66                 return log_error_errno(r, "Failed to set bus name: %m");
67
68         r = sd_bus_set_address(b, dest);
69         if (r < 0)
70                 return log_error_errno(r, "Failed to set address to connect to: %m");
71
72         r = sd_bus_negotiate_fds(b, negotiate_fds);
73         if (r < 0)
74                 return log_error_errno(r, "Failed to set FD negotiation: %m");
75
76         r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
77         if (r < 0)
78                 return log_error_errno(r, "Failed to set credential negotiation: %m");
79
80         if (p->local_creds.pid > 0) {
81                 b->fake_pids.pid = p->local_creds.pid;
82                 b->fake_pids_valid = true;
83
84                 b->fake_creds.uid = p->local_creds.uid;
85                 b->fake_creds.euid = UID_INVALID;
86                 b->fake_creds.suid = UID_INVALID;
87                 b->fake_creds.fsuid = UID_INVALID;
88                 b->fake_creds.gid = p->local_creds.gid;
89                 b->fake_creds.egid = GID_INVALID;
90                 b->fake_creds.sgid = GID_INVALID;
91                 b->fake_creds.fsgid = GID_INVALID;
92                 b->fake_creds_valid = true;
93         }
94
95         if (local_sec) {
96                 b->fake_label = strdup(local_sec);
97                 if (!b->fake_label)
98                         return log_oom();
99         }
100
101         b->manual_peer_interface = true;
102
103         r = sd_bus_start(b);
104         if (r < 0)
105                 return log_error_errno(r, "Failed to start bus client: %m");
106
107         p->dest_bus = b;
108         b = NULL;
109         return 0;
110 }
111
112 static int proxy_create_local(Proxy *p, int in_fd, int out_fd, bool negotiate_fds) {
113         _cleanup_bus_close_unref_ sd_bus *b = NULL;
114         sd_id128_t server_id;
115         int r;
116
117         r = sd_bus_new(&b);
118         if (r < 0)
119                 return log_error_errno(r, "Failed to allocate bus: %m");
120
121         r = sd_bus_set_fd(b, in_fd, out_fd);
122         if (r < 0)
123                 return log_error_errno(r, "Failed to set fds: %m");
124
125         r = sd_bus_get_bus_id(p->dest_bus, &server_id);
126         if (r < 0)
127                 return log_error_errno(r, "Failed to get server ID: %m");
128
129         r = sd_bus_set_server(b, 1, server_id);
130         if (r < 0)
131                 return log_error_errno(r, "Failed to set server mode: %m");
132
133         r = sd_bus_negotiate_fds(b, negotiate_fds);
134         if (r < 0)
135                 return log_error_errno(r, "Failed to set FD negotiation: %m");
136
137         r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
138         if (r < 0)
139                 return log_error_errno(r, "Failed to set credential negotiation: %m");
140
141         r = sd_bus_set_anonymous(b, true);
142         if (r < 0)
143                 return log_error_errno(r, "Failed to set anonymous authentication: %m");
144
145         b->manual_peer_interface = true;
146
147         r = sd_bus_start(b);
148         if (r < 0)
149                 return log_error_errno(r, "Failed to start bus client: %m");
150
151         p->local_bus = b;
152         b = NULL;
153         return 0;
154 }
155
156 static int proxy_prepare_matches(Proxy *p) {
157         _cleanup_free_ char *match = NULL;
158         const char *unique;
159         int r;
160
161         if (!p->dest_bus->is_kernel)
162                 return 0;
163
164         r = sd_bus_get_unique_name(p->dest_bus, &unique);
165         if (r < 0)
166                 return log_error_errno(r, "Failed to get unique name: %m");
167
168         match = strjoin("type='signal',"
169                         "sender='org.freedesktop.DBus',"
170                         "path='/org/freedesktop/DBus',"
171                         "interface='org.freedesktop.DBus',"
172                         "member='NameOwnerChanged',"
173                         "arg1='",
174                         unique,
175                         "'",
176                         NULL);
177         if (!match)
178                 return log_oom();
179
180         r = sd_bus_add_match(p->dest_bus, NULL, match, NULL, NULL);
181         if (r < 0)
182                 return log_error_errno(r, "Failed to add match for NameLost: %m");
183
184         free(match);
185         match = strjoin("type='signal',"
186                         "sender='org.freedesktop.DBus',"
187                         "path='/org/freedesktop/DBus',"
188                         "interface='org.freedesktop.DBus',"
189                         "member='NameOwnerChanged',"
190                         "arg2='",
191                         unique,
192                         "'",
193                         NULL);
194         if (!match)
195                 return log_oom();
196
197         r = sd_bus_add_match(p->dest_bus, NULL, match, NULL, NULL);
198         if (r < 0)
199                 return log_error_errno(r, "Failed to add match for NameAcquired: %m");
200
201         return 0;
202 }
203
204 int proxy_new(Proxy **out, int in_fd, int out_fd, const char *dest) {
205         _cleanup_(proxy_freep) Proxy *p = NULL;
206         _cleanup_free_ char *local_sec = NULL;
207         bool is_unix;
208         int r;
209
210         p = new0(Proxy, 1);
211         if (!p)
212                 return log_oom();
213
214         p->local_in = in_fd;
215         p->local_out = out_fd;
216
217         p->owned_names = set_new(&string_hash_ops);
218         if (!p->owned_names)
219                 return log_oom();
220
221         is_unix = sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
222                   sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
223
224         if (is_unix) {
225                 (void) getpeercred(in_fd, &p->local_creds);
226                 (void) getpeersec(in_fd, &local_sec);
227         }
228
229         r = proxy_create_dest(p, dest, local_sec, is_unix);
230         if (r < 0)
231                 return r;
232
233         r = proxy_create_local(p, in_fd, out_fd, is_unix);
234         if (r < 0)
235                 return r;
236
237         r = proxy_prepare_matches(p);
238         if (r < 0)
239                 return r;
240
241         *out = p;
242         p = NULL;
243         return 0;
244 }
245
246 Proxy *proxy_free(Proxy *p) {
247         if (!p)
248                 return NULL;
249
250         sd_bus_close_unrefp(&p->local_bus);
251         sd_bus_close_unrefp(&p->dest_bus);
252         set_free_free(p->owned_names);
253         free(p);
254
255         return NULL;
256 }
257
258 int proxy_set_policy(Proxy *p, SharedPolicy *sp, char **configuration) {
259         _cleanup_strv_free_ char **strv = NULL;
260         Policy *policy;
261         int r;
262
263         assert(p);
264         assert(sp);
265
266         /* no need to load legacy policy if destination is not kdbus */
267         if (!p->dest_bus->is_kernel)
268                 return 0;
269
270         p->policy = sp;
271
272         policy = shared_policy_acquire(sp);
273         if (policy) {
274                 /* policy already pre-loaded */
275                 shared_policy_release(sp, policy);
276                 return 0;
277         }
278
279         if (!configuration) {
280                 const char *scope;
281
282                 r = sd_bus_get_scope(p->dest_bus, &scope);
283                 if (r < 0)
284                         return log_error_errno(r, "Couldn't determine bus scope: %m");
285
286                 if (streq(scope, "system"))
287                         strv = strv_new("/etc/dbus-1/system.conf",
288                                         "/etc/dbus-1/system.d/",
289                                         "/etc/dbus-1/system-local.conf",
290                                         NULL);
291                 else if (streq(scope, "user"))
292                         strv = strv_new("/etc/dbus-1/session.conf",
293                                         "/etc/dbus-1/session.d/",
294                                         "/etc/dbus-1/session-local.conf",
295                                         NULL);
296                 else
297                         return log_error("Unknown scope %s, don't know which policy to load. Refusing.", scope);
298
299                 if (!strv)
300                         return log_oom();
301
302                 configuration = strv;
303         }
304
305         return shared_policy_preload(sp, configuration);
306 }
307
308 int proxy_hello_policy(Proxy *p, uid_t original_uid) {
309         Policy *policy;
310         int r = 0;
311
312         assert(p);
313
314         if (!p->policy)
315                 return 0;
316
317         policy = shared_policy_acquire(p->policy);
318
319         if (p->local_creds.uid == original_uid)
320                 log_debug("Permitting access, since bus owner matches bus client.");
321         else if (policy_check_hello(policy, p->local_creds.uid, p->local_creds.gid))
322                 log_debug("Permitting access due to XML policy.");
323         else
324                 r = log_error_errno(EPERM, "Policy denied connection.");
325
326         shared_policy_release(p->policy, policy);
327
328         return r;
329 }
330
331 static int proxy_wait(Proxy *p) {
332         uint64_t timeout_dest, timeout_local, t;
333         int events_dest, events_local, fd;
334         struct timespec _ts, *ts;
335         struct pollfd *pollfd;
336         int r;
337
338         assert(p);
339
340         fd = sd_bus_get_fd(p->dest_bus);
341         if (fd < 0)
342                 return log_error_errno(fd, "Failed to get fd: %m");
343
344         events_dest = sd_bus_get_events(p->dest_bus);
345         if (events_dest < 0)
346                 return log_error_errno(events_dest, "Failed to get events mask: %m");
347
348         r = sd_bus_get_timeout(p->dest_bus, &timeout_dest);
349         if (r < 0)
350                 return log_error_errno(r, "Failed to get timeout: %m");
351
352         events_local = sd_bus_get_events(p->local_bus);
353         if (events_local < 0)
354                 return log_error_errno(events_local, "Failed to get events mask: %m");
355
356         r = sd_bus_get_timeout(p->local_bus, &timeout_local);
357         if (r < 0)
358                 return log_error_errno(r, "Failed to get timeout: %m");
359
360         t = timeout_dest;
361         if (t == (uint64_t) -1 || (timeout_local != (uint64_t) -1 && timeout_local < timeout_dest))
362                 t = timeout_local;
363
364         if (t == (uint64_t) -1)
365                 ts = NULL;
366         else {
367                 usec_t nw;
368
369                 nw = now(CLOCK_MONOTONIC);
370                 if (t > nw)
371                         t -= nw;
372                 else
373                         t = 0;
374
375                 ts = timespec_store(&_ts, t);
376         }
377
378         pollfd = (struct pollfd[3]) {
379                 { .fd = fd,           .events = events_dest,            },
380                 { .fd = p->local_in,  .events = events_local & POLLIN,  },
381                 { .fd = p->local_out, .events = events_local & POLLOUT, },
382         };
383
384         r = ppoll(pollfd, 3, ts, NULL);
385         if (r < 0)
386                 return log_error_errno(errno, "ppoll() failed: %m");
387
388         return 0;
389 }
390
391 static int handle_policy_error(sd_bus_message *m, int r) {
392         if (r == -ESRCH || r == -ENXIO)
393                 return synthetic_reply_method_errorf(m, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", m->destination);
394
395         return r;
396 }
397
398 static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *policy, const struct ucred *our_ucred, Set *owned_names) {
399         int r;
400
401         assert(from);
402         assert(to);
403         assert(m);
404
405         if (!policy)
406                 return 0;
407
408         /*
409          * dbus-1 distinguishes expected and non-expected replies by tracking
410          * method-calls and timeouts. By default, DENY rules are *NEVER* applied
411          * on expected replies, unless explicitly specified. But we dont track
412          * method-calls, thus, we cannot know whether a reply is expected.
413          * Fortunately, the kdbus forbids non-expected replies, so we can safely
414          * ignore any policy on those and let the kernel deal with it.
415          *
416          * TODO: To be correct, we should only ignore policy-tags that are
417          * applied on non-expected replies. However, so far we don't parse those
418          * tags so we let everything pass. I haven't seen a DENY policy tag on
419          * expected-replies, ever, so don't bother..
420          */
421         if (m->reply_cookie > 0)
422                 return 0;
423
424         if (from->is_kernel) {
425                 uid_t sender_uid = UID_INVALID;
426                 gid_t sender_gid = GID_INVALID;
427                 char **sender_names = NULL;
428                 bool granted = false;
429
430                 /* Driver messages are always OK */
431                 if (streq_ptr(m->sender, "org.freedesktop.DBus"))
432                         return 0;
433
434                 /* The message came from the kernel, and is sent to our legacy client. */
435                 sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
436
437                 (void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
438                 (void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
439
440                 if (sender_uid == UID_INVALID || sender_gid == GID_INVALID) {
441                         _cleanup_bus_creds_unref_ sd_bus_creds *sender_creds = NULL;
442
443                         /* If the message came from another legacy
444                          * client, then the message creds will be
445                          * missing, simply because on legacy clients
446                          * per-message creds were unknown. In this
447                          * case, query the creds of the peer
448                          * instead. */
449
450                         r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_UID|SD_BUS_CREDS_GID, true, &sender_creds);
451                         if (r < 0)
452                                 return handle_policy_error(m, r);
453
454                         (void) sd_bus_creds_get_uid(sender_creds, &sender_uid);
455                         (void) sd_bus_creds_get_gid(sender_creds, &sender_gid);
456                 }
457
458                 /* First check whether the sender can send the message to our name */
459                 if (set_isempty(owned_names)) {
460                         if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, NULL, m->path, m->interface, m->member, false))
461                                 granted = true;
462                 } else {
463                         Iterator i;
464                         char *n;
465
466                         SET_FOREACH(n, owned_names, i)
467                                 if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, n, m->path, m->interface, m->member, false)) {
468                                         granted = true;
469                                         break;
470                                 }
471                 }
472
473                 if (granted) {
474                         /* Then check whether us (the recipient) can receive from the sender's name */
475                         if (strv_isempty(sender_names)) {
476                                 if (policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, m->path, m->interface, m->member, false))
477                                         return 0;
478                         } else {
479                                 char **n;
480
481                                 STRV_FOREACH(n, sender_names) {
482                                         if (policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, *n, m->path, m->interface, m->member, false))
483                                                 return 0;
484                                 }
485                         }
486                 }
487
488                 /* Return an error back to the caller */
489                 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
490                         return synthetic_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML receiver policy.");
491
492                 /* Return 1, indicating that the message shall not be processed any further */
493                 return 1;
494         }
495
496         if (to->is_kernel) {
497                 _cleanup_bus_creds_unref_ sd_bus_creds *destination_creds = NULL;
498                 uid_t destination_uid = UID_INVALID;
499                 gid_t destination_gid = GID_INVALID;
500                 const char *destination_unique = NULL;
501                 char **destination_names = NULL;
502                 bool granted = false;
503
504                 /* Driver messages are always OK */
505                 if (streq_ptr(m->destination, "org.freedesktop.DBus"))
506                         return 0;
507
508                 /* The message came from the legacy client, and is sent to kdbus. */
509                 if (m->destination) {
510                         r = bus_get_name_creds_kdbus(to, m->destination,
511                                                      SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME|
512                                                      SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID,
513                                                      true, &destination_creds);
514                         if (r < 0)
515                                 return handle_policy_error(m, r);
516
517                         r = sd_bus_creds_get_unique_name(destination_creds, &destination_unique);
518                         if (r < 0)
519                                 return handle_policy_error(m, r);
520
521                         sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
522
523                         (void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
524                         (void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
525                 }
526
527                 /* First check if we (the sender) can send to this name */
528                 if (strv_isempty(destination_names)) {
529                         if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, m->path, m->interface, m->member, true))
530                                 granted = true;
531                 } else {
532                         char **n;
533
534                         STRV_FOREACH(n, destination_names) {
535                                 if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, *n, m->path, m->interface, m->member, true)) {
536
537                                         /* If we made a receiver decision,
538                                            then remember which name's policy
539                                            we used, and to which unique ID it
540                                            mapped when we made the
541                                            decision. Then, let's pass this to
542                                            the kernel when sending the
543                                            message, so that it refuses the
544                                            operation should the name and
545                                            unique ID not map to each other
546                                            anymore. */
547
548                                         r = free_and_strdup(&m->destination_ptr, *n);
549                                         if (r < 0)
550                                                 return r;
551
552                                         r = bus_kernel_parse_unique_name(destination_unique, &m->verify_destination_id);
553                                         if (r < 0)
554                                                 break;
555
556                                         granted = true;
557                                         break;
558                                 }
559                         }
560                 }
561
562                 /* Then check if the recipient can receive from our name */
563                 if (granted) {
564                         if (sd_bus_message_is_signal(m, NULL, NULL)) {
565                                 /* If we forward a signal from dbus-1 to kdbus,
566                                  * we have no idea who the recipient is.
567                                  * Therefore, we cannot apply any dbus-1
568                                  * receiver policies that match on receiver
569                                  * credentials. We know sd-bus always sets
570                                  * KDBUS_MSG_SIGNAL, so the kernel applies
571                                  * receiver policies to the message. Therefore,
572                                  * skip policy checks in this case. */
573                                 return 0;
574                         } else if (set_isempty(owned_names)) {
575                                 if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, NULL, m->path, m->interface, m->member, true))
576                                         return 0;
577                         } else {
578                                 Iterator i;
579                                 char *n;
580
581                                 SET_FOREACH(n, owned_names, i)
582                                         if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, n, m->path, m->interface, m->member, true))
583                                                 return 0;
584                         }
585                 }
586
587                 /* Return an error back to the caller */
588                 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
589                         return synthetic_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML sender policy.");
590
591                 /* Return 1, indicating that the message shall not be processed any further */
592                 return 1;
593         }
594
595         return 0;
596 }
597
598 static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, SharedPolicy *sp, const struct ucred *our_ucred, Set *owned_names) {
599         Policy *policy;
600         int r;
601
602         assert(sp);
603
604         policy = shared_policy_acquire(sp);
605         r = process_policy_unlocked(from, to, m, policy, our_ucred, owned_names);
606         shared_policy_release(sp, policy);
607
608         return r;
609 }
610
611 static int process_hello(Proxy *p, sd_bus_message *m) {
612         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
613         bool is_hello;
614         int r;
615
616         assert(p);
617         assert(m);
618
619         /* As reaction to hello we need to respond with two messages:
620          * the callback reply and the NameAcquired for the unique
621          * name, since hello is otherwise obsolete on kdbus. */
622
623         is_hello =
624                 sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "Hello") &&
625                 streq_ptr(m->destination, "org.freedesktop.DBus");
626
627         if (!is_hello) {
628                 if (p->got_hello)
629                         return 0;
630
631                 return log_error_errno(-EIO, "First packet isn't hello (it's %s.%s), aborting.", m->interface, m->member);
632         }
633
634         if (p->got_hello)
635                 return log_error_errno(-EIO, "Got duplicate hello, aborting.");
636
637         p->got_hello = true;
638
639         if (!p->dest_bus->is_kernel)
640                 return 0;
641
642         r = sd_bus_message_new_method_return(m, &n);
643         if (r < 0)
644                 return log_error_errno(r, "Failed to generate HELLO reply: %m");
645
646         r = sd_bus_message_append(n, "s", p->dest_bus->unique_name);
647         if (r < 0)
648                 return log_error_errno(r, "Failed to append unique name to HELLO reply: %m");
649
650         r = bus_message_append_sender(n, "org.freedesktop.DBus");
651         if (r < 0)
652                 return log_error_errno(r, "Failed to append sender to HELLO reply: %m");
653
654         r = bus_seal_synthetic_message(p->local_bus, n);
655         if (r < 0)
656                 return log_error_errno(r, "Failed to seal HELLO reply: %m");
657
658         r = sd_bus_send(p->local_bus, n, NULL);
659         if (r < 0)
660                 return log_error_errno(r, "Failed to send HELLO reply: %m");
661
662         n = sd_bus_message_unref(n);
663         r = sd_bus_message_new_signal(
664                         p->local_bus,
665                         &n,
666                         "/org/freedesktop/DBus",
667                         "org.freedesktop.DBus",
668                         "NameAcquired");
669         if (r < 0)
670                 return log_error_errno(r, "Failed to allocate initial NameAcquired message: %m");
671
672         r = sd_bus_message_append(n, "s", p->dest_bus->unique_name);
673         if (r < 0)
674                 return log_error_errno(r, "Failed to append unique name to NameAcquired message: %m");
675
676         r = bus_message_append_sender(n, "org.freedesktop.DBus");
677         if (r < 0)
678                 return log_error_errno(r, "Failed to append sender to NameAcquired message: %m");
679
680         r = bus_seal_synthetic_message(p->local_bus, n);
681         if (r < 0)
682                 return log_error_errno(r, "Failed to seal NameAcquired message: %m");
683
684         r = sd_bus_send(p->local_bus, n, NULL);
685         if (r < 0)
686                 return log_error_errno(r, "Failed to send NameAcquired message: %m");
687
688         return 1;
689 }
690
691 static int patch_sender(sd_bus *a, sd_bus_message *m) {
692         char **well_known = NULL;
693         sd_bus_creds *c;
694         int r;
695
696         assert(a);
697         assert(m);
698
699         if (!a->is_kernel)
700                 return 0;
701
702         /* We will change the sender of messages from the bus driver
703          * so that they originate from the bus driver. This is a
704          * speciality originating from dbus1, where the bus driver did
705          * not have a unique id, but only the well-known name. */
706
707         c = sd_bus_message_get_creds(m);
708         if (!c)
709                 return 0;
710
711         r = sd_bus_creds_get_well_known_names(c, &well_known);
712         if (r < 0)
713                 return r;
714
715         if (strv_contains(well_known, "org.freedesktop.DBus"))
716                 m->sender = "org.freedesktop.DBus";
717
718         return 0;
719 }
720
721 static int proxy_process_dest_to_local(Proxy *p) {
722         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
723         int r;
724
725         assert(p);
726
727         r = sd_bus_process(p->dest_bus, &m);
728         if (r < 0) {
729                 /* treat 'connection reset by peer' as clean exit condition */
730                 if (r != -ECONNRESET)
731                         log_error_errno(r, "Failed to process destination bus: %m");
732                 return r;
733         }
734
735         if (r == 0)
736                 return 0;
737         if (!m)
738                 return 1;
739
740         /* We officially got EOF, let's quit */
741         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected"))
742                 return -ECONNRESET;
743
744         r = synthesize_name_acquired(p->dest_bus, p->local_bus, m);
745         if (r < 0)
746                 return log_error_errno(r, "Failed to synthesize message: %m");
747
748         patch_sender(p->dest_bus, m);
749
750         if (p->policy) {
751                 r = process_policy(p->dest_bus, p->local_bus, m, p->policy, &p->local_creds, p->owned_names);
752                 if (r < 0)
753                         return log_error_errno(r, "Failed to process policy: %m");
754                 else if (r > 0)
755                         return 1;
756         }
757
758         r = sd_bus_send(p->local_bus, m, NULL);
759         if (r < 0) {
760                 if (r == -EPERM && m->reply_cookie > 0) {
761                         /* If the peer tries to send a reply and it is rejected with EPERM
762                          * by the kernel, we ignore the error. This catches cases where the
763                          * original method-call didn't had EXPECT_REPLY set, but the proxy-peer
764                          * still sends a reply. This is allowed in dbus1, but not in kdbus. We
765                          * don't want to track reply-windows in the proxy, so we simply ignore
766                          * EPERM for all replies. The only downside is, that callers are no
767                          * longer notified if their replies are dropped. However, this is
768                          * equivalent to the caller's timeout to expire, so this should be
769                          * acceptable. Nobody sane sends replies without a matching method-call,
770                          * so nobody should care. */
771                         return 1;
772                 } else {
773                         if (r != -ECONNRESET)
774                                 log_error_errno(r, "Failed to send message to client: %m");
775                         return r;
776                 }
777         }
778
779         return 1;
780 }
781
782 static int proxy_process_local_to_dest(Proxy *p) {
783         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
784         int r;
785
786         assert(p);
787
788         r = sd_bus_process(p->local_bus, &m);
789         if (r < 0) {
790                 /* treat 'connection reset by peer' as clean exit condition */
791                 if (r != -ECONNRESET)
792                         log_error_errno(r, "Failed to process local bus: %m");
793                 return r;
794         }
795
796         if (r == 0)
797                 return 0;
798         if (!m)
799                 return 1;
800
801         /* We officially got EOF, let's quit */
802         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected"))
803                 return -ECONNRESET;
804
805         r = process_hello(p, m);
806         if (r < 0)
807                 return log_error_errno(r, "Failed to process HELLO: %m");
808         else if (r > 0)
809                 return 1;
810
811         r = bus_proxy_process_driver(p->dest_bus, p->local_bus, m, p->policy, &p->local_creds, p->owned_names);
812         if (r < 0)
813                 return log_error_errno(r, "Failed to process driver calls: %m");
814         else if (r > 0)
815                 return 1;
816
817         for (;;) {
818                 if (p->policy) {
819                         r = process_policy(p->local_bus, p->dest_bus, m, p->policy, &p->local_creds, p->owned_names);
820                         if (r < 0)
821                                 return log_error_errno(r, "Failed to process policy: %m");
822                         else if (r > 0)
823                                 return 1;
824                 }
825
826                 r = sd_bus_send(p->dest_bus, m, NULL);
827                 if (r < 0) {
828                         if (r == -EREMCHG) {
829                                 /* The name database changed since the policy check, hence let's check again */
830                                 continue;
831                         } else if (r == -EPERM && m->reply_cookie > 0) {
832                                 /* see above why EPERM is ignored for replies */
833                                 return 1;
834                         } else {
835                                 if (r != -ECONNRESET)
836                                         log_error_errno(r, "Failed to send message to bus: %m");
837                                 return r;
838                         }
839                 }
840
841                 break;
842         }
843
844         return 1;
845 }
846
847 int proxy_run(Proxy *p) {
848         int r;
849
850         assert(p);
851
852         for (;;) {
853                 bool busy = false;
854
855                 if (p->got_hello) {
856                         /* Read messages from bus, to pass them on to our client */
857                         r = proxy_process_dest_to_local(p);
858                         if (r == -ECONNRESET)
859                                 return 0;
860                         else if (r < 0)
861                                 return r;
862                         else if (r > 0)
863                                 busy = true;
864                 }
865
866                 /* Read messages from our client, to pass them on to the bus */
867                 r = proxy_process_local_to_dest(p);
868                 if (r == -ECONNRESET)
869                         return 0;
870                 else if (r < 0)
871                         return r;
872                 else if (r > 0)
873                         busy = true;
874
875                 if (!busy) {
876                         r = proxy_wait(p);
877                         if (r < 0)
878                                 return r;
879                 }
880         }
881
882         return 0;
883 }