chiark / gitweb /
bus: send memfds as payload only on directed messages and for large parts
[elogind.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
41
42         if (p == NULL)
43                 return NULL;
44
45         if (old_base == new_base)
46                 return (void*) p;
47
48         if ((uint8_t*) p < (uint8_t*) old_base)
49                 return (void*) p;
50
51         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
52                 return (void*) p;
53
54         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
55 }
56
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
58         assert(m);
59         assert(part);
60
61         if (part->memfd >= 0) {
62                 /* If we can reuse the memfd, try that. For that it
63                  * can't be sealed yet. */
64
65                 if (!part->sealed)
66                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
67                 else {
68                         if (part->size > 0)
69                                 assert_se(munmap(part->data, PAGE_ALIGN(part->size)) == 0);
70
71                         close_nointr_nofail(part->memfd);
72                 }
73
74         } else if (part->munmap_this)
75                 munmap(part->data, part->mapped);
76         else if (part->free_this)
77                 free(part->data);
78
79         if (part != &m->body)
80                 free(part);
81 }
82
83 static void message_reset_parts(sd_bus_message *m) {
84         struct bus_body_part *part;
85
86         assert(m);
87
88         part = &m->body;
89         while (m->n_body_parts > 0) {
90                 struct bus_body_part *next = part->next;
91                 message_free_part(m, part);
92                 part = next;
93                 m->n_body_parts--;
94         }
95
96         m->body_end = NULL;
97
98         m->cached_rindex_part = NULL;
99         m->cached_rindex_part_begin = 0;
100 }
101
102 static void message_reset_containers(sd_bus_message *m) {
103         unsigned i;
104
105         assert(m);
106
107         for (i = 0; i < m->n_containers; i++)
108                 free(m->containers[i].signature);
109
110         free(m->containers);
111         m->containers = NULL;
112
113         m->n_containers = 0;
114         m->root_container.index = 0;
115 }
116
117 static void message_free(sd_bus_message *m) {
118         assert(m);
119
120         if (m->free_header)
121                 free(m->header);
122
123         message_reset_parts(m);
124
125         if (m->free_kdbus)
126                 free(m->kdbus);
127
128         if (m->release_kdbus)
129                 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
130
131         if (m->free_fds) {
132                 close_many(m->fds, m->n_fds);
133                 free(m->fds);
134         }
135
136         if (m->bus)
137                 sd_bus_unref(m->bus);
138
139         if (m->iovec != m->iovec_fixed)
140                 free(m->iovec);
141
142         free(m->cmdline_array);
143
144         message_reset_containers(m);
145         free(m->root_container.signature);
146
147         free(m->peeked_signature);
148
149         free(m->unit);
150         free(m->user_unit);
151         free(m->session);
152         free(m);
153 }
154
155 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
156         void *op, *np;
157         size_t old_size, new_size, start;
158
159         assert(m);
160
161         if (m->poisoned)
162                 return NULL;
163
164         old_size = sizeof(struct bus_header) + m->header->fields_size;
165         start = ALIGN_TO(old_size, align);
166         new_size = start + sz;
167
168         if (old_size == new_size)
169                 return (uint8_t*) m->header + old_size;
170
171         if (new_size > (size_t) ((uint32_t) -1))
172                 goto poison;
173
174         if (m->free_header) {
175                 np = realloc(m->header, ALIGN8(new_size));
176                 if (!np)
177                         goto poison;
178         } else {
179                 /* Initially, the header is allocated as part of of
180                  * the sd_bus_message itself, let's replace it by
181                  * dynamic data */
182
183                 np = malloc(ALIGN8(new_size));
184                 if (!np)
185                         goto poison;
186
187                 memcpy(np, m->header, sizeof(struct bus_header));
188         }
189
190         /* Zero out padding */
191         if (start > old_size)
192                 memset((uint8_t*) np + old_size, 0, start - old_size);
193
194         op = m->header;
195         m->header = np;
196         m->header->fields_size = new_size - sizeof(struct bus_header);
197
198         /* Adjust quick access pointers */
199         m->path = adjust_pointer(m->path, op, old_size, m->header);
200         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
201         m->member = adjust_pointer(m->member, op, old_size, m->header);
202         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
203         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
204         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
205
206         m->free_header = true;
207
208         return (uint8_t*) np + start;
209
210 poison:
211         m->poisoned = true;
212         return NULL;
213 }
214
215 static int message_append_field_string(
216                 sd_bus_message *m,
217                 uint8_t h,
218                 char type,
219                 const char *s,
220                 const char **ret) {
221
222         size_t l;
223         uint8_t *p;
224
225         assert(m);
226
227         l = strlen(s);
228         if (l > (size_t) (uint32_t) -1)
229                 return -EINVAL;
230
231         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
232         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
233         if (!p)
234                 return -ENOMEM;
235
236         p[0] = h;
237         p[1] = 1;
238         p[2] = type;
239         p[3] = 0;
240
241         ((uint32_t*) p)[1] = l;
242         memcpy(p + 8, s, l + 1);
243
244         if (ret)
245                 *ret = (char*) p + 8;
246
247         return 0;
248 }
249
250 static int message_append_field_signature(
251                 sd_bus_message *m,
252                 uint8_t h,
253                 const char *s,
254                 const char **ret) {
255
256         size_t l;
257         uint8_t *p;
258
259         assert(m);
260
261         l = strlen(s);
262         if (l > 255)
263                 return -EINVAL;
264
265         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
266         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
267         if (!p)
268                 return -ENOMEM;
269
270         p[0] = h;
271         p[1] = 1;
272         p[2] = SD_BUS_TYPE_SIGNATURE;
273         p[3] = 0;
274         p[4] = l;
275         memcpy(p + 5, s, l + 1);
276
277         if (ret)
278                 *ret = (const char*) p + 5;
279
280         return 0;
281 }
282
283 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
284         uint8_t *p;
285
286         assert(m);
287
288         /* field id byte + signature length + signature 'u' + NUL + value */
289         p = message_extend_fields(m, 8, 4 + 4);
290         if (!p)
291                 return -ENOMEM;
292
293         p[0] = h;
294         p[1] = 1;
295         p[2] = SD_BUS_TYPE_UINT32;
296         p[3] = 0;
297
298         ((uint32_t*) p)[1] = x;
299
300         return 0;
301 }
302
303 int bus_message_from_header(
304                 void *buffer,
305                 size_t length,
306                 int *fds,
307                 unsigned n_fds,
308                 const struct ucred *ucred,
309                 const char *label,
310                 size_t extra,
311                 sd_bus_message **ret) {
312
313         sd_bus_message *m;
314         struct bus_header *h;
315         size_t a, label_sz;
316
317         assert(buffer || length <= 0);
318         assert(fds || n_fds <= 0);
319         assert(ret);
320
321         if (length < sizeof(struct bus_header))
322                 return -EBADMSG;
323
324         h = buffer;
325         if (h->version != 1)
326                 return -EBADMSG;
327
328         if (h->serial == 0)
329                 return -EBADMSG;
330
331         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
332                 return -EBADMSG;
333
334         if (h->endian != SD_BUS_LITTLE_ENDIAN &&
335             h->endian != SD_BUS_BIG_ENDIAN)
336                 return -EBADMSG;
337
338         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
339
340         if (label) {
341                 label_sz = strlen(label);
342                 a += label_sz + 1;
343         }
344
345         m = malloc0(a);
346         if (!m)
347                 return -ENOMEM;
348
349         m->n_ref = 1;
350         m->sealed = true;
351         m->header = h;
352         m->fds = fds;
353         m->n_fds = n_fds;
354
355         if (ucred) {
356                 m->uid = ucred->uid;
357                 m->pid = ucred->pid;
358                 m->gid = ucred->gid;
359                 m->uid_valid = m->gid_valid = true;
360         }
361
362         if (label) {
363                 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
364                 memcpy(m->label, label, label_sz + 1);
365         }
366
367         *ret = m;
368         return 0;
369 }
370
371 int bus_message_from_malloc(
372                 void *buffer,
373                 size_t length,
374                 int *fds,
375                 unsigned n_fds,
376                 const struct ucred *ucred,
377                 const char *label,
378                 sd_bus_message **ret) {
379
380         sd_bus_message *m;
381         int r;
382
383         r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
384         if (r < 0)
385                 return r;
386
387         if (length != BUS_MESSAGE_SIZE(m)) {
388                 r = -EBADMSG;
389                 goto fail;
390         }
391
392         m->n_body_parts = 1;
393         m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
394         m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
395         m->body.sealed = true;
396         m->body.memfd = -1;
397
398         m->n_iovec = 1;
399         m->iovec = m->iovec_fixed;
400         m->iovec[0].iov_base = buffer;
401         m->iovec[0].iov_len = length;
402
403         r = bus_message_parse_fields(m);
404         if (r < 0)
405                 goto fail;
406
407         /* We take possession of the memory and fds now */
408         m->free_header = true;
409         m->free_fds = true;
410
411         *ret = m;
412         return 0;
413
414 fail:
415         message_free(m);
416         return r;
417 }
418
419 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
420         sd_bus_message *m;
421
422         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
423         if (!m)
424                 return NULL;
425
426         m->n_ref = 1;
427         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
428         m->header->endian = SD_BUS_NATIVE_ENDIAN;
429         m->header->type = type;
430         m->header->version = bus ? bus->message_version : 1;
431         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
432
433         if (bus)
434                 m->bus = sd_bus_ref(bus);
435
436         return m;
437 }
438
439 int sd_bus_message_new_signal(
440                 sd_bus *bus,
441                 const char *path,
442                 const char *interface,
443                 const char *member,
444                 sd_bus_message **m) {
445
446         sd_bus_message *t;
447         int r;
448
449         if (!path)
450                 return -EINVAL;
451         if (!interface)
452                 return -EINVAL;
453         if (!member)
454                 return -EINVAL;
455         if (!m)
456                 return -EINVAL;
457         if (bus && bus->state == BUS_UNSET)
458                 return -ENOTCONN;
459
460         t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
461         if (!t)
462                 return -ENOMEM;
463
464         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
465
466         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
467         if (r < 0)
468                 goto fail;
469         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
470         if (r < 0)
471                 goto fail;
472         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
473         if (r < 0)
474                 goto fail;
475
476         *m = t;
477         return 0;
478
479 fail:
480         sd_bus_message_unref(t);
481         return r;
482 }
483
484 int sd_bus_message_new_method_call(
485                 sd_bus *bus,
486                 const char *destination,
487                 const char *path,
488                 const char *interface,
489                 const char *member,
490                 sd_bus_message **m) {
491
492         sd_bus_message *t;
493         int r;
494
495         if (!path)
496                 return -EINVAL;
497         if (!member)
498                 return -EINVAL;
499         if (!m)
500                 return -EINVAL;
501         if (bus && bus->state == BUS_UNSET)
502                 return -ENOTCONN;
503
504         t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
505         if (!t)
506                 return -ENOMEM;
507
508         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
509         if (r < 0)
510                 goto fail;
511         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
512         if (r < 0)
513                 goto fail;
514
515         if (interface) {
516                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
517                 if (r < 0)
518                         goto fail;
519         }
520
521         if (destination) {
522                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
523                 if (r < 0)
524                         goto fail;
525         }
526
527         *m = t;
528         return 0;
529
530 fail:
531         message_free(t);
532         return r;
533 }
534
535 static int message_new_reply(
536                 sd_bus *bus,
537                 sd_bus_message *call,
538                 uint8_t type,
539                 sd_bus_message **m) {
540
541         sd_bus_message *t;
542         int r;
543
544         if (!call)
545                 return -EINVAL;
546         if (!call->sealed)
547                 return -EPERM;
548         if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
549                 return -EINVAL;
550         if (!m)
551                 return -EINVAL;
552         if (bus && bus->state == BUS_UNSET)
553                 return -ENOTCONN;
554
555         t = message_new(bus, type);
556         if (!t)
557                 return -ENOMEM;
558
559         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
560         t->reply_serial = BUS_MESSAGE_SERIAL(call);
561
562         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
563         if (r < 0)
564                 goto fail;
565
566         if (call->sender) {
567                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
568                 if (r < 0)
569                         goto fail;
570         }
571
572         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
573
574         *m = t;
575         return 0;
576
577 fail:
578         message_free(t);
579         return r;
580 }
581
582 int sd_bus_message_new_method_return(
583                 sd_bus *bus,
584                 sd_bus_message *call,
585                 sd_bus_message **m) {
586
587         return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
588 }
589
590 int sd_bus_message_new_method_error(
591                 sd_bus *bus,
592                 sd_bus_message *call,
593                 const sd_bus_error *e,
594                 sd_bus_message **m) {
595
596         sd_bus_message *t;
597         int r;
598
599         if (!sd_bus_error_is_set(e))
600                 return -EINVAL;
601         if (!m)
602                 return -EINVAL;
603
604         r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
605         if (r < 0)
606                 return r;
607
608         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
609         if (r < 0)
610                 goto fail;
611
612         if (e->message) {
613                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
614                 if (r < 0)
615                         goto fail;
616         }
617
618         *m = t;
619         return 0;
620
621 fail:
622         message_free(t);
623         return r;
624 }
625
626 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
627         if (!m)
628                 return NULL;
629
630         assert(m->n_ref > 0);
631         m->n_ref++;
632
633         return m;
634 }
635
636 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
637         if (!m)
638                 return NULL;
639
640         assert(m->n_ref > 0);
641         m->n_ref--;
642
643         if (m->n_ref <= 0)
644                 message_free(m);
645
646         return NULL;
647 }
648
649 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
650         if (!m)
651                 return -EINVAL;
652         if (!type)
653                 return -EINVAL;
654
655         *type = m->header->type;
656         return 0;
657 }
658
659 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
660         if (!m)
661                 return -EINVAL;
662         if (!serial)
663                 return -EINVAL;
664         if (m->header->serial == 0)
665                 return -ENOENT;
666
667         *serial = BUS_MESSAGE_SERIAL(m);
668         return 0;
669 }
670
671 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
672         if (!m)
673                 return -EINVAL;
674         if (!serial)
675                 return -EINVAL;
676         if (m->reply_serial == 0)
677                 return -ENOENT;
678
679         *serial = m->reply_serial;
680         return 0;
681 }
682
683 int sd_bus_message_get_no_reply(sd_bus_message *m) {
684         if (!m)
685                 return -EINVAL;
686
687         return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
688 }
689
690 const char *sd_bus_message_get_path(sd_bus_message *m) {
691         if (!m)
692                 return NULL;
693
694         return m->path;
695 }
696
697 const char *sd_bus_message_get_interface(sd_bus_message *m) {
698         if (!m)
699                 return NULL;
700
701         return m->interface;
702 }
703
704 const char *sd_bus_message_get_member(sd_bus_message *m) {
705         if (!m)
706                 return NULL;
707
708         return m->member;
709 }
710 const char *sd_bus_message_get_destination(sd_bus_message *m) {
711         if (!m)
712                 return NULL;
713
714         return m->destination;
715 }
716
717 const char *sd_bus_message_get_sender(sd_bus_message *m) {
718         if (!m)
719                 return NULL;
720
721         return m->sender;
722 }
723
724 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
725         if (!m)
726                 return NULL;
727
728         if (!sd_bus_error_is_set(&m->error))
729                 return NULL;
730
731         return &m->error;
732 }
733
734 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
735         if (!m)
736                 return -EINVAL;
737         if (!uid)
738                 return -EINVAL;
739         if (!m->uid_valid)
740                 return -ESRCH;
741
742         *uid = m->uid;
743         return 0;
744 }
745
746 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
747         if (!m)
748                 return -EINVAL;
749         if (!gid)
750                 return -EINVAL;
751         if (!m->gid_valid)
752                 return -ESRCH;
753
754         *gid = m->gid;
755         return 0;
756 }
757
758 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
759         if (!m)
760                 return -EINVAL;
761         if (!pid)
762                 return -EINVAL;
763         if (m->pid <= 0)
764                 return -ESRCH;
765
766         *pid = m->pid;
767         return 0;
768 }
769
770 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
771         if (!m)
772                 return -EINVAL;
773         if (!tid)
774                 return -EINVAL;
775         if (m->tid <= 0)
776                 return -ESRCH;
777
778         *tid = m->tid;
779         return 0;
780 }
781
782 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
783         if (!m)
784                 return -EINVAL;
785         if (!usec)
786                 return -EINVAL;
787         if (m->pid_starttime <= 0)
788                 return -ESRCH;
789
790         *usec = m->pid_starttime;
791         return 0;
792 }
793
794 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
795         if (!m)
796                 return -EINVAL;
797         if (!m->label)
798                 return -ESRCH;
799
800         *ret = m->label;
801         return 0;
802 }
803
804 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
805         if (!m)
806                 return -EINVAL;
807         if (!usec)
808                 return -EINVAL;
809         if (m->monotonic <= 0)
810                 return -ESRCH;
811
812         *usec = m->monotonic;
813         return 0;
814 }
815
816 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
817         if (!m)
818                 return -EINVAL;
819         if (!usec)
820                 return -EINVAL;
821         if (m->realtime <= 0)
822                 return -ESRCH;
823
824         *usec = m->realtime;
825         return 0;
826 }
827
828 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
829         if (!m)
830                 return -EINVAL;
831         if (!ret)
832                 return -EINVAL;
833         if (!m->comm)
834                 return -ESRCH;
835
836         *ret = m->comm;
837         return 0;
838 }
839
840 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
841         if (!m)
842                 return -EINVAL;
843         if (!ret)
844                 return -EINVAL;
845         if (!m->tid_comm)
846                 return -ESRCH;
847
848         *ret = m->tid_comm;
849         return 0;
850 }
851
852 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
853         if (!m)
854                 return -EINVAL;
855         if (!ret)
856                 return -EINVAL;
857         if (!m->exe)
858                 return -ESRCH;
859
860         *ret = m->exe;
861         return 0;
862 }
863
864 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
865         if (!m)
866                 return -EINVAL;
867         if (!ret)
868                 return -EINVAL;
869         if (!m->cgroup)
870                 return -ESRCH;
871
872         *ret = m->cgroup;
873         return 0;
874 }
875
876 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
877         int r;
878
879         if (!m)
880                 return -EINVAL;
881         if (!ret)
882                 return -EINVAL;
883         if (!m->cgroup)
884                 return -ESRCH;
885
886         if (!m->unit) {
887                 r = cg_path_get_unit(m->cgroup, &m->unit);
888                 if (r < 0)
889                         return r;
890         }
891
892         *ret = m->unit;
893         return 0;
894 }
895
896 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
897         int r;
898
899         if (!m)
900                 return -EINVAL;
901         if (!ret)
902                 return -EINVAL;
903         if (!m->cgroup)
904                 return -ESRCH;
905
906         if (!m->user_unit) {
907                 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
908                 if (r < 0)
909                         return r;
910         }
911
912         *ret = m->user_unit;
913         return 0;
914 }
915
916 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
917         int r;
918
919         if (!m)
920                 return -EINVAL;
921         if (!ret)
922                 return -EINVAL;
923         if (!m->cgroup)
924                 return -ESRCH;
925
926         if (!m->session) {
927                 r = cg_path_get_session(m->cgroup, &m->session);
928                 if (r < 0)
929                         return r;
930         }
931
932         *ret = m->session;
933         return 0;
934 }
935
936 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
937         if (!m)
938                 return -EINVAL;
939         if (!uid)
940                 return -EINVAL;
941         if (!m->cgroup)
942                 return -ESRCH;
943
944         return cg_path_get_owner_uid(m->cgroup, uid);
945 }
946
947 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
948         size_t n, i;
949         const char *p;
950         bool first;
951
952         if (!m)
953                 return -EINVAL;
954
955         if (!m->cmdline)
956                 return -ENOENT;
957
958         for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
959                 if (*p == 0)
960                         n++;
961
962         m->cmdline_array = new(char*, n + 1);
963         if (!m->cmdline_array)
964                 return -ENOMEM;
965
966         for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
967                 if (first)
968                         m->cmdline_array[i++] = (char*) p;
969
970                 first = *p == 0;
971         }
972
973         m->cmdline_array[i] = NULL;
974         *cmdline = m->cmdline_array;
975
976         return 0;
977 }
978
979 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
980         if (!m)
981                 return -EINVAL;
982         if (!sessionid)
983                 return -EINVAL;
984         if (!m->audit)
985                 return -ESRCH;
986
987         *sessionid = m->audit->sessionid;
988         return 0;
989 }
990
991 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
992         if (!m)
993                 return -EINVAL;
994         if (!uid)
995                 return -EINVAL;
996         if (!m->audit)
997                 return -ESRCH;
998
999         *uid = m->audit->loginuid;
1000         return 0;
1001 }
1002
1003 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1004         unsigned sz;
1005
1006         if (!m)
1007                 return -EINVAL;
1008         if (capability < 0)
1009                 return -EINVAL;
1010         if (!m->capability)
1011                 return -ESRCH;
1012
1013         sz = m->capability_size / 4;
1014         if ((unsigned) capability >= sz*8)
1015                 return 0;
1016
1017         return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1018 }
1019
1020 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1021         if (!m)
1022                 return -EINVAL;
1023
1024         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
1025                 return 0;
1026
1027         if (interface && (!m->interface || !streq(m->interface, interface)))
1028                 return 0;
1029
1030         if (member &&  (!m->member || !streq(m->member, member)))
1031                 return 0;
1032
1033         return 1;
1034 }
1035
1036 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1037         if (!m)
1038                 return -EINVAL;
1039
1040         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1041                 return 0;
1042
1043         if (interface && (!m->interface || !streq(m->interface, interface)))
1044                 return 0;
1045
1046         if (member &&  (!m->member || !streq(m->member, member)))
1047                 return 0;
1048
1049         return 1;
1050 }
1051
1052 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1053         if (!m)
1054                 return -EINVAL;
1055
1056         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
1057                 return 0;
1058
1059         if (name && (!m->error.name || !streq(m->error.name, name)))
1060                 return 0;
1061
1062         return 1;
1063 }
1064
1065 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1066         if (!m)
1067                 return -EINVAL;
1068         if (m->sealed)
1069                 return -EPERM;
1070         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
1071                 return -EPERM;
1072
1073         if (b)
1074                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1075         else
1076                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1077
1078         return 0;
1079 }
1080
1081 static struct bus_container *message_get_container(sd_bus_message *m) {
1082         assert(m);
1083
1084         if (m->n_containers == 0)
1085                 return &m->root_container;
1086
1087         assert(m->containers);
1088         return m->containers + m->n_containers - 1;
1089 }
1090
1091 struct bus_body_part *message_append_part(sd_bus_message *m) {
1092         struct bus_body_part *part;
1093
1094         assert(m);
1095
1096         if (m->poisoned)
1097                 return NULL;
1098
1099         if (m->n_body_parts <= 0) {
1100                 part = &m->body;
1101                 zero(*part);
1102         } else {
1103                 assert(m->body_end);
1104
1105                 part = new0(struct bus_body_part, 1);
1106                 if (!part) {
1107                         m->poisoned = true;
1108                         return NULL;
1109                 }
1110
1111                 m->body_end->next = part;
1112         }
1113
1114         part->memfd = -1;
1115         m->body_end = part;
1116         m->n_body_parts ++;
1117
1118         return part;
1119 }
1120
1121 static void part_zero(struct bus_body_part *part, size_t sz) {
1122         assert(part);
1123         assert(sz > 0);
1124         assert(sz < 8);
1125
1126         /* All other fields can be left in their defaults */
1127         assert(!part->data);
1128         assert(part->memfd < 0);
1129
1130         part->size = sz;
1131         part->is_zero = true;
1132         part->sealed = true;
1133 }
1134
1135 static int part_make_space(
1136                 struct sd_bus_message *m,
1137                 struct bus_body_part *part,
1138                 size_t sz,
1139                 void **q) {
1140
1141         void *n;
1142         int r;
1143
1144         assert(m);
1145         assert(part);
1146         assert(!part->sealed);
1147
1148         if (m->poisoned)
1149                 return -ENOMEM;
1150
1151         if (!part->data && part->memfd < 0)
1152                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1153
1154         if (part->memfd >= 0) {
1155                 uint64_t u = sz;
1156
1157                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1158                 if (r < 0) {
1159                         m->poisoned = true;
1160                         return -errno;
1161                 }
1162
1163                 if (!part->data || sz > part->mapped) {
1164                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1165
1166                         if (part->mapped <= 0)
1167                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1168                         else
1169                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1170
1171                         if (n == MAP_FAILED) {
1172                                 m->poisoned = true;
1173                                 return -errno;
1174                         }
1175
1176                         part->mapped = psz;
1177                         part->data = n;
1178                         part->munmap_this = true;
1179                 }
1180         } else {
1181                 n = realloc(part->data, sz);
1182                 if (!n) {
1183                         m->poisoned = true;
1184                         return -ENOMEM;
1185                 }
1186
1187                 part->data = n;
1188                 part->free_this = true;
1189         }
1190
1191         if (q)
1192                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1193
1194         part->size = sz;
1195         return 0;
1196 }
1197
1198 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1199         struct bus_container *c;
1200
1201         assert(m);
1202
1203         if (expand <= 0)
1204                 return;
1205
1206         /* Update counters */
1207         for (c = m->containers; c < m->containers + m->n_containers; c++)
1208                 if (c->array_size)
1209                         *c->array_size += expand;
1210
1211 }
1212
1213 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1214         struct bus_body_part *part = NULL;
1215         size_t start_body, end_body, padding, start_part, end_part, added;
1216         bool add_new_part;
1217         void *p;
1218         int r;
1219
1220         assert(m);
1221         assert(align > 0);
1222         assert(!m->sealed);
1223
1224         if (m->poisoned)
1225                 return NULL;
1226
1227         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1228         end_body = start_body + sz;
1229
1230         padding = start_body - m->header->body_size;
1231         added = padding + sz;
1232
1233         /* Check for 32bit overflows */
1234         if (end_body > (size_t) ((uint32_t) -1)) {
1235                 m->poisoned = true;
1236                 return NULL;
1237         }
1238
1239         add_new_part =
1240                 m->n_body_parts <= 0 ||
1241                 m->body_end->sealed ||
1242                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1243
1244         if (add_new_part) {
1245                 if (padding > 0) {
1246                         part = message_append_part(m);
1247                         if (!part)
1248                                 return NULL;
1249
1250                         part_zero(part, padding);
1251                 }
1252
1253                 part = message_append_part(m);
1254                 if (!part)
1255                         return NULL;
1256
1257                 r = part_make_space(m, part, sz, &p);
1258                 if (r < 0)
1259                         return NULL;
1260         } else {
1261                 struct bus_container *c;
1262                 void *op;
1263                 size_t os;
1264
1265                 part = m->body_end;
1266                 op = part->data;
1267                 os = part->size;
1268
1269                 start_part = ALIGN_TO(part->size, align);
1270                 end_part = start_part + sz;
1271
1272                 r = part_make_space(m, part, end_part, &p);
1273                 if (r < 0)
1274                         return NULL;
1275
1276                 if (padding > 0) {
1277                         memset(p, 0, padding);
1278                         p = (uint8_t*) p + padding;
1279                 }
1280
1281                 /* Readjust pointers */
1282                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1283                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1284
1285                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1286         }
1287
1288         m->header->body_size = end_body;
1289         message_extend_containers(m, added);
1290
1291         return p;
1292 }
1293
1294 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1295         struct bus_container *c;
1296         ssize_t align, sz;
1297         uint32_t k;
1298         void *a;
1299         char *e = NULL;
1300         int fd = -1;
1301         uint32_t fdi = 0;
1302         int r;
1303
1304         if (!m)
1305                 return -EINVAL;
1306         if (!p)
1307                 return -EINVAL;
1308         if (m->sealed)
1309                 return -EPERM;
1310         if (!bus_type_is_basic(type))
1311                 return -EINVAL;
1312         if (m->poisoned)
1313                 return -ESTALE;
1314
1315         c = message_get_container(m);
1316
1317         if (c->signature && c->signature[c->index]) {
1318                 /* Container signature is already set */
1319
1320                 if (c->signature[c->index] != type)
1321                         return -ENXIO;
1322         } else {
1323                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1324                 if (c->enclosing != 0)
1325                         return -ENXIO;
1326
1327                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1328                 if (!e) {
1329                         m->poisoned = true;
1330                         return -ENOMEM;
1331                 }
1332         }
1333
1334         switch (type) {
1335
1336         case SD_BUS_TYPE_STRING:
1337         case SD_BUS_TYPE_OBJECT_PATH:
1338
1339                 align = 4;
1340                 sz = 4 + strlen(p) + 1;
1341                 break;
1342
1343         case SD_BUS_TYPE_SIGNATURE:
1344
1345                 align = 1;
1346                 sz = 1 + strlen(p) + 1;
1347                 break;
1348
1349         case SD_BUS_TYPE_BOOLEAN:
1350                 align = sz = 4;
1351
1352                 assert_cc(sizeof(int) == sizeof(uint32_t));
1353                 memcpy(&k, p, 4);
1354                 k = !!k;
1355                 p = &k;
1356                 break;
1357
1358         case SD_BUS_TYPE_UNIX_FD: {
1359                 int z, *f;
1360
1361                 if (!m->allow_fds) {
1362                         r = -ENOTSUP;
1363                         goto fail;
1364                 }
1365
1366                 align = sz = 4;
1367
1368                 z = *(int*) p;
1369                 if (z < 0) {
1370                         r = -EINVAL;
1371                         goto fail;
1372                 }
1373
1374                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1375                 if (fd < 0) {
1376                         r = -errno;
1377                         goto fail;
1378                 }
1379
1380                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1381                 if (!f) {
1382                         m->poisoned = true;
1383                         r = -ENOMEM;
1384                         goto fail;
1385                 }
1386
1387                 fdi = m->n_fds;
1388                 f[fdi] = fd;
1389                 m->fds = f;
1390                 m->free_fds = true;
1391                 break;
1392         }
1393
1394         default:
1395                 align = bus_type_get_alignment(type);
1396                 sz = bus_type_get_size(type);
1397                 break;
1398         }
1399
1400         assert(align > 0);
1401         assert(sz > 0);
1402
1403         a = message_extend_body(m, align, sz);
1404         if (!a) {
1405                 r = -ENOMEM;
1406                 goto fail;
1407         }
1408
1409         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1410                 *(uint32_t*) a = sz - 5;
1411                 memcpy((uint8_t*) a + 4, p, sz - 4);
1412
1413                 if (stored)
1414                         *stored = (const uint8_t*) a + 4;
1415
1416         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1417                 *(uint8_t*) a = sz - 1;
1418                 memcpy((uint8_t*) a + 1, p, sz - 1);
1419
1420                 if (stored)
1421                         *stored = (const uint8_t*) a + 1;
1422         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1423                 *(uint32_t*) a = fdi;
1424
1425                 if (stored)
1426                         *stored = a;
1427
1428                 m->n_fds ++;
1429
1430         } else {
1431                 memcpy(a, p, sz);
1432
1433                 if (stored)
1434                         *stored = a;
1435         }
1436
1437         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1438                 c->index++;
1439
1440         return 0;
1441
1442 fail:
1443         if (fd >= 0)
1444                 close_nointr_nofail(fd);
1445
1446         return r;
1447 }
1448
1449 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1450         return message_append_basic(m, type, p, NULL);
1451 }
1452
1453 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1454         struct bus_container *c;
1455         char *e;
1456         void *a;
1457
1458         if (!m)
1459                 return -EINVAL;
1460         if (!s)
1461                 return -EINVAL;
1462         if (m->sealed)
1463                 return -EPERM;
1464         if (m->poisoned)
1465                 return -ESTALE;
1466
1467         c = message_get_container(m);
1468
1469         if (c->signature && c->signature[c->index]) {
1470                 /* Container signature is already set */
1471
1472                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1473                         return -ENXIO;
1474         } else {
1475                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1476                 if (c->enclosing != 0)
1477                         return -ENXIO;
1478
1479                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1480                 if (!e) {
1481                         m->poisoned = true;
1482                         return -ENOMEM;
1483                 }
1484         }
1485
1486
1487         a = message_extend_body(m, 4, 4 + size + 1);
1488         if (!a)
1489                 return -ENOMEM;
1490
1491         *(uint32_t*) a = size;
1492         *s = (char*) a + 4;
1493
1494         (*s)[size] = 0;
1495
1496         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1497                 c->index++;
1498
1499         return 0;
1500 }
1501
1502 static int bus_message_open_array(
1503                 sd_bus_message *m,
1504                 struct bus_container *c,
1505                 const char *contents,
1506                 uint32_t **array_size) {
1507
1508         unsigned nindex;
1509         char *e = NULL;
1510         void *a, *op;
1511         int alignment;
1512         size_t os;
1513         struct bus_body_part *o;
1514
1515         assert(m);
1516         assert(c);
1517         assert(contents);
1518         assert(array_size);
1519
1520         if (!signature_is_single(contents))
1521                 return -EINVAL;
1522
1523         alignment = bus_type_get_alignment(contents[0]);
1524         if (alignment < 0)
1525                 return alignment;
1526
1527         if (c->signature && c->signature[c->index]) {
1528
1529                 /* Verify the existing signature */
1530
1531                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1532                         return -ENXIO;
1533
1534                 if (!startswith(c->signature + c->index + 1, contents))
1535                         return -ENXIO;
1536
1537                 nindex = c->index + 1 + strlen(contents);
1538         } else {
1539                 if (c->enclosing != 0)
1540                         return -ENXIO;
1541
1542                 /* Extend the existing signature */
1543
1544                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1545                 if (!e) {
1546                         m->poisoned = true;
1547                         return -ENOMEM;
1548                 }
1549
1550                 nindex = e - c->signature;
1551         }
1552
1553         a = message_extend_body(m, 4, 4);
1554         if (!a)
1555                 return -ENOMEM;
1556
1557         o = m->body_end;
1558         op = m->body_end->data;
1559         os = m->body_end->size;
1560
1561         /* Add alignment between size and first element */
1562         if (!message_extend_body(m, alignment, 0))
1563                 return -ENOMEM;
1564
1565         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1566                 c->index = nindex;
1567
1568         /* location of array size might have changed so let's readjust a */
1569         if (o == m->body_end)
1570                 a = adjust_pointer(a, op, os, m->body_end->data);
1571
1572         *(uint32_t*) a = 0;
1573         *array_size = a;
1574         return 0;
1575 }
1576
1577 static int bus_message_open_variant(
1578                 sd_bus_message *m,
1579                 struct bus_container *c,
1580                 const char *contents) {
1581
1582         char *e = NULL;
1583         size_t l;
1584         void *a;
1585
1586         assert(m);
1587         assert(c);
1588         assert(contents);
1589
1590         if (!signature_is_single(contents))
1591                 return -EINVAL;
1592
1593         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1594                 return -EINVAL;
1595
1596         if (c->signature && c->signature[c->index]) {
1597
1598                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1599                         return -ENXIO;
1600
1601         } else {
1602                 if (c->enclosing != 0)
1603                         return -ENXIO;
1604
1605                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1606                 if (!e) {
1607                         m->poisoned = true;
1608                         return -ENOMEM;
1609                 }
1610         }
1611
1612         l = strlen(contents);
1613         a = message_extend_body(m, 1, 1 + l + 1);
1614         if (!a)
1615                 return -ENOMEM;
1616
1617         *(uint8_t*) a = l;
1618         memcpy((uint8_t*) a + 1, contents, l + 1);
1619
1620         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1621                 c->index++;
1622
1623         return 0;
1624 }
1625
1626 static int bus_message_open_struct(
1627                 sd_bus_message *m,
1628                 struct bus_container *c,
1629                 const char *contents) {
1630
1631         size_t nindex;
1632         char *e = NULL;
1633
1634         assert(m);
1635         assert(c);
1636         assert(contents);
1637
1638         if (!signature_is_valid(contents, false))
1639                 return -EINVAL;
1640
1641         if (c->signature && c->signature[c->index]) {
1642                 size_t l;
1643
1644                 l = strlen(contents);
1645
1646                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1647                     !startswith(c->signature + c->index + 1, contents) ||
1648                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1649                         return -ENXIO;
1650
1651                 nindex = c->index + 1 + l + 1;
1652         } else {
1653                 if (c->enclosing != 0)
1654                         return -ENXIO;
1655
1656                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1657                 if (!e) {
1658                         m->poisoned = true;
1659                         return -ENOMEM;
1660                 }
1661
1662                 nindex = e - c->signature;
1663         }
1664
1665         /* Align contents to 8 byte boundary */
1666         if (!message_extend_body(m, 8, 0))
1667                 return -ENOMEM;
1668
1669         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1670                 c->index = nindex;
1671
1672         return 0;
1673 }
1674
1675 static int bus_message_open_dict_entry(
1676                 sd_bus_message *m,
1677                 struct bus_container *c,
1678                 const char *contents) {
1679
1680         size_t nindex;
1681
1682         assert(m);
1683         assert(c);
1684         assert(contents);
1685
1686         if (!signature_is_pair(contents))
1687                 return -EINVAL;
1688
1689         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1690                 return -ENXIO;
1691
1692         if (c->signature && c->signature[c->index]) {
1693                 size_t l;
1694
1695                 l = strlen(contents);
1696
1697                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1698                     !startswith(c->signature + c->index + 1, contents) ||
1699                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1700                         return -ENXIO;
1701
1702                 nindex = c->index + 1 + l + 1;
1703         } else
1704                 return -ENXIO;
1705
1706         /* Align contents to 8 byte boundary */
1707         if (!message_extend_body(m, 8, 0))
1708                 return -ENOMEM;
1709
1710         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1711                 c->index = nindex;
1712
1713         return 0;
1714 }
1715
1716 int sd_bus_message_open_container(
1717                 sd_bus_message *m,
1718                 char type,
1719                 const char *contents) {
1720
1721         struct bus_container *c, *w;
1722         uint32_t *array_size = NULL;
1723         char *signature;
1724         size_t before;
1725         int r;
1726
1727         if (!m)
1728                 return -EINVAL;
1729         if (m->sealed)
1730                 return -EPERM;
1731         if (!contents)
1732                 return -EINVAL;
1733         if (m->poisoned)
1734                 return -ESTALE;
1735
1736         /* Make sure we have space for one more container */
1737         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1738         if (!w) {
1739                 m->poisoned = true;
1740                 return -ENOMEM;
1741         }
1742
1743         m->containers = w;
1744
1745         c = message_get_container(m);
1746
1747         signature = strdup(contents);
1748         if (!signature) {
1749                 m->poisoned = true;
1750                 return -ENOMEM;
1751         }
1752
1753         /* Save old index in the parent container, in case we have to
1754          * abort this container */
1755         c->saved_index = c->index;
1756         before = m->header->body_size;
1757
1758         if (type == SD_BUS_TYPE_ARRAY)
1759                 r = bus_message_open_array(m, c, contents, &array_size);
1760         else if (type == SD_BUS_TYPE_VARIANT)
1761                 r = bus_message_open_variant(m, c, contents);
1762         else if (type == SD_BUS_TYPE_STRUCT)
1763                 r = bus_message_open_struct(m, c, contents);
1764         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1765                 r = bus_message_open_dict_entry(m, c, contents);
1766         else
1767                 r = -EINVAL;
1768
1769         if (r < 0) {
1770                 free(signature);
1771                 return r;
1772         }
1773
1774         /* OK, let's fill it in */
1775         w += m->n_containers++;
1776         w->enclosing = type;
1777         w->signature = signature;
1778         w->index = 0;
1779         w->array_size = array_size;
1780         w->before = before;
1781         w->begin = m->rindex;
1782
1783         return 0;
1784 }
1785
1786 int sd_bus_message_close_container(sd_bus_message *m) {
1787         struct bus_container *c;
1788
1789         if (!m)
1790                 return -EINVAL;
1791         if (m->sealed)
1792                 return -EPERM;
1793         if (m->n_containers <= 0)
1794                 return -EINVAL;
1795         if (m->poisoned)
1796                 return -ESTALE;
1797
1798         c = message_get_container(m);
1799         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1800                 if (c->signature && c->signature[c->index] != 0)
1801                         return -EINVAL;
1802
1803         free(c->signature);
1804         m->n_containers--;
1805
1806         return 0;
1807 }
1808
1809 typedef struct {
1810         const char *types;
1811         unsigned n_struct;
1812         unsigned n_array;
1813 } TypeStack;
1814
1815 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1816         assert(stack);
1817         assert(max > 0);
1818
1819         if (*i >= max)
1820                 return -EINVAL;
1821
1822         stack[*i].types = types;
1823         stack[*i].n_struct = n_struct;
1824         stack[*i].n_array = n_array;
1825         (*i)++;
1826
1827         return 0;
1828 }
1829
1830 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1831         assert(stack);
1832         assert(max > 0);
1833         assert(types);
1834         assert(n_struct);
1835         assert(n_array);
1836
1837         if (*i <= 0)
1838                 return 0;
1839
1840         (*i)--;
1841         *types = stack[*i].types;
1842         *n_struct = stack[*i].n_struct;
1843         *n_array = stack[*i].n_array;
1844
1845         return 1;
1846 }
1847
1848 int bus_message_append_ap(
1849                 sd_bus_message *m,
1850                 const char *types,
1851                 va_list ap) {
1852
1853         unsigned n_array, n_struct;
1854         TypeStack stack[BUS_CONTAINER_DEPTH];
1855         unsigned stack_ptr = 0;
1856         int r;
1857
1858         assert(m);
1859
1860         if (!types)
1861                 return 0;
1862
1863         n_array = (unsigned) -1;
1864         n_struct = strlen(types);
1865
1866         for (;;) {
1867                 const char *t;
1868
1869                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1870                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1871                         if (r < 0)
1872                                 return r;
1873                         if (r == 0)
1874                                 break;
1875
1876                         r = sd_bus_message_close_container(m);
1877                         if (r < 0)
1878                                 return r;
1879
1880                         continue;
1881                 }
1882
1883                 t = types;
1884                 if (n_array != (unsigned) -1)
1885                         n_array --;
1886                 else {
1887                         types ++;
1888                         n_struct--;
1889                 }
1890
1891                 switch (*t) {
1892
1893                 case SD_BUS_TYPE_BYTE: {
1894                         uint8_t x;
1895
1896                         x = (uint8_t) va_arg(ap, int);
1897                         r = sd_bus_message_append_basic(m, *t, &x);
1898                         break;
1899                 }
1900
1901                 case SD_BUS_TYPE_BOOLEAN:
1902                 case SD_BUS_TYPE_INT32:
1903                 case SD_BUS_TYPE_UINT32:
1904                 case SD_BUS_TYPE_UNIX_FD: {
1905                         uint32_t x;
1906
1907                         /* We assume a boolean is the same as int32_t */
1908                         assert_cc(sizeof(int32_t) == sizeof(int));
1909
1910                         x = va_arg(ap, uint32_t);
1911                         r = sd_bus_message_append_basic(m, *t, &x);
1912                         break;
1913                 }
1914
1915                 case SD_BUS_TYPE_INT16:
1916                 case SD_BUS_TYPE_UINT16: {
1917                         uint16_t x;
1918
1919                         x = (uint16_t) va_arg(ap, int);
1920                         r = sd_bus_message_append_basic(m, *t, &x);
1921                         break;
1922                 }
1923
1924                 case SD_BUS_TYPE_INT64:
1925                 case SD_BUS_TYPE_UINT64:
1926                 case SD_BUS_TYPE_DOUBLE: {
1927                         uint64_t x;
1928
1929                         x = va_arg(ap, uint64_t);
1930                         r = sd_bus_message_append_basic(m, *t, &x);
1931                         break;
1932                 }
1933
1934                 case SD_BUS_TYPE_STRING:
1935                 case SD_BUS_TYPE_OBJECT_PATH:
1936                 case SD_BUS_TYPE_SIGNATURE: {
1937                         const char *x;
1938
1939                         x = va_arg(ap, const char*);
1940                         r = sd_bus_message_append_basic(m, *t, x);
1941                         break;
1942                 }
1943
1944                 case SD_BUS_TYPE_ARRAY: {
1945                         size_t k;
1946
1947                         r = signature_element_length(t + 1, &k);
1948                         if (r < 0)
1949                                 return r;
1950
1951                         {
1952                                 char s[k + 1];
1953                                 memcpy(s, t + 1, k);
1954                                 s[k] = 0;
1955
1956                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1957                                 if (r < 0)
1958                                         return r;
1959                         }
1960
1961                         if (n_array == (unsigned) -1) {
1962                                 types += k;
1963                                 n_struct -= k;
1964                         }
1965
1966                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1967                         if (r < 0)
1968                                 return r;
1969
1970                         types = t + 1;
1971                         n_struct = k;
1972                         n_array = va_arg(ap, unsigned);
1973
1974                         break;
1975                 }
1976
1977                 case SD_BUS_TYPE_VARIANT: {
1978                         const char *s;
1979
1980                         s = va_arg(ap, const char*);
1981                         if (!s)
1982                                 return -EINVAL;
1983
1984                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1985                         if (r < 0)
1986                                 return r;
1987
1988                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1989                         if (r < 0)
1990                                 return r;
1991
1992                         types = s;
1993                         n_struct = strlen(s);
1994                         n_array = (unsigned) -1;
1995
1996                         break;
1997                 }
1998
1999                 case SD_BUS_TYPE_STRUCT_BEGIN:
2000                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2001                         size_t k;
2002
2003                         r = signature_element_length(t, &k);
2004                         if (r < 0)
2005                                 return r;
2006
2007                         {
2008                                 char s[k - 1];
2009
2010                                 memcpy(s, t + 1, k - 2);
2011                                 s[k - 2] = 0;
2012
2013                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2014                                 if (r < 0)
2015                                         return r;
2016                         }
2017
2018                         if (n_array == (unsigned) -1) {
2019                                 types += k - 1;
2020                                 n_struct -= k - 1;
2021                         }
2022
2023                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2024                         if (r < 0)
2025                                 return r;
2026
2027                         types = t + 1;
2028                         n_struct = k - 2;
2029                         n_array = (unsigned) -1;
2030
2031                         break;
2032                 }
2033
2034                 default:
2035                         r = -EINVAL;
2036                 }
2037
2038                 if (r < 0)
2039                         return r;
2040         }
2041
2042         return 0;
2043 }
2044
2045 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2046         va_list ap;
2047         int r;
2048
2049         if (!m)
2050                 return -EINVAL;
2051         if (m->sealed)
2052                 return -EPERM;
2053         if (m->poisoned)
2054                 return -ESTALE;
2055         if (!types)
2056                 return 0;
2057
2058         va_start(ap, types);
2059         r = bus_message_append_ap(m, types, ap);
2060         va_end(ap);
2061
2062         return r;
2063 }
2064
2065 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2066         ssize_t align, sz;
2067         void *a;
2068         int r;
2069
2070         if (!m)
2071                 return -EINVAL;
2072         if (m->sealed)
2073                 return -EPERM;
2074         if (!bus_type_is_trivial(type))
2075                 return -EINVAL;
2076         if (!ptr && size > 0)
2077                 return -EINVAL;
2078         if (m->poisoned)
2079                 return -ESTALE;
2080
2081         align = bus_type_get_alignment(type);
2082         sz = bus_type_get_size(type);
2083
2084         assert_se(align > 0);
2085         assert_se(sz > 0);
2086
2087         if (size % sz != 0)
2088                 return -EINVAL;
2089
2090         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2091         if (r < 0)
2092                 return r;
2093
2094         a = message_extend_body(m, align, size);
2095         if (!a)
2096                 return -ENOMEM;
2097
2098         r = sd_bus_message_close_container(m);
2099         if (r < 0)
2100                 return r;
2101
2102         *ptr = a;
2103         return 0;
2104 }
2105
2106 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2107         int r;
2108         void *p;
2109
2110         if (!ptr && size > 0)
2111                 return -EINVAL;
2112
2113         r = sd_bus_message_append_array_space(m, type, size, &p);
2114         if (r < 0)
2115                 return r;
2116
2117         if (size > 0)
2118                 memcpy(p, ptr, size);
2119
2120         return 0;
2121 }
2122
2123 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2124         _cleanup_close_ int copy_fd = -1;
2125         struct bus_body_part *part;
2126         ssize_t align, sz;
2127         uint64_t size;
2128         void *a;
2129         int r;
2130
2131         if (!m)
2132                 return -EINVAL;
2133         if (!memfd)
2134                 return -EINVAL;
2135         if (m->sealed)
2136                 return -EPERM;
2137         if (!bus_type_is_trivial(type))
2138                 return -EINVAL;
2139         if (m->poisoned)
2140                 return -ESTALE;
2141
2142         r = sd_memfd_set_sealed(memfd, true);
2143         if (r < 0)
2144                 return r;
2145
2146         copy_fd = sd_memfd_dup_fd(memfd);
2147         if (copy_fd < 0)
2148                 return copy_fd;
2149
2150         r = sd_memfd_get_size(memfd, &size);
2151         if (r < 0)
2152                 return r;
2153
2154         align = bus_type_get_alignment(type);
2155         sz = bus_type_get_size(type);
2156
2157         assert_se(align > 0);
2158         assert_se(sz > 0);
2159
2160         if (size % sz != 0)
2161                 return -EINVAL;
2162
2163         if (size > (size_t) (uint32_t) -1)
2164                 return -EINVAL;
2165
2166         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2167         if (r < 0)
2168                 return r;
2169
2170         a = message_extend_body(m, align, 0);
2171         if (!a)
2172                 return -ENOMEM;
2173
2174         part = message_append_part(m);
2175         if (!part)
2176                 return -ENOMEM;
2177
2178         part->memfd = copy_fd;
2179         part->sealed = true;
2180         part->size = size;
2181         copy_fd = -1;
2182
2183         message_extend_containers(m, size);
2184         m->header->body_size += size;
2185
2186         return sd_bus_message_close_container(m);
2187 }
2188
2189 int bus_body_part_map(struct bus_body_part *part) {
2190         void *p;
2191         size_t psz;
2192
2193         assert_se(part);
2194
2195         if (part->data)
2196                 return 0;
2197
2198         if (part->size <= 0)
2199                 return 0;
2200
2201         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2202         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2203                 static const uint8_t zeroes[7] = { };
2204                 part->data = (void*) zeroes;
2205                 return 0;
2206         }
2207
2208         psz = PAGE_ALIGN(part->size);
2209
2210         if (part->memfd >= 0)
2211                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2212         else if (part->is_zero)
2213                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2214         else
2215                 return -EINVAL;
2216
2217         if (p == MAP_FAILED)
2218                 return -errno;
2219
2220         part->mapped = psz;
2221         part->data = p;
2222         part->munmap_this = true;
2223
2224         return 0;
2225 }
2226
2227 void bus_body_part_unmap(struct bus_body_part *part) {
2228
2229         assert_se(part);
2230
2231         if (part->memfd < 0)
2232                 return;
2233
2234         if (!part->data)
2235                 return;
2236
2237         if (!part->munmap_this)
2238                 return;
2239
2240         assert_se(munmap(part->data, part->mapped) == 0);
2241
2242         part->data = NULL;
2243         part->mapped = 0;
2244         part->munmap_this = false;
2245
2246         return;
2247 }
2248
2249 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2250         size_t k, start, end;
2251
2252         assert(rindex);
2253         assert(align > 0);
2254
2255         start = ALIGN_TO((size_t) *rindex, align);
2256         end = start + nbytes;
2257
2258         if (end > sz)
2259                 return -EBADMSG;
2260
2261         /* Verify that padding is 0 */
2262         for (k = *rindex; k < start; k++)
2263                 if (((const uint8_t*) p)[k] != 0)
2264                         return -EBADMSG;
2265
2266         if (r)
2267                 *r = (uint8_t*) p + start;
2268
2269         *rindex = end;
2270
2271         return 1;
2272 }
2273
2274 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2275         struct bus_container *c;
2276
2277         assert(m);
2278
2279         c = message_get_container(m);
2280         if (!c->array_size)
2281                 return false;
2282
2283         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2284 }
2285
2286 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2287         struct bus_body_part *part;
2288         size_t begin;
2289         int r;
2290
2291         assert(m);
2292
2293         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2294                 part = m->cached_rindex_part;
2295                 begin = m->cached_rindex_part_begin;
2296         } else {
2297                 part = &m->body;
2298                 begin = 0;
2299         }
2300
2301         while (part) {
2302                 if (index < begin)
2303                         return NULL;
2304
2305                 if (index + sz <= begin + part->size) {
2306
2307                         r = bus_body_part_map(part);
2308                         if (r < 0)
2309                                 return NULL;
2310
2311                         if (p)
2312                                 *p = (uint8_t*) part->data + index - begin;
2313
2314                         m->cached_rindex_part = part;
2315                         m->cached_rindex_part_begin = begin;
2316
2317                         return part;
2318                 }
2319
2320                 begin += part->size;
2321                 part = part->next;
2322         }
2323
2324         return NULL;
2325 }
2326
2327 static int message_peek_body(
2328                 sd_bus_message *m,
2329                 size_t *rindex,
2330                 size_t align,
2331                 size_t nbytes,
2332                 void **ret) {
2333
2334         size_t k, start, end, padding;
2335         struct bus_body_part *part;
2336         uint8_t *q;
2337
2338         assert(m);
2339         assert(rindex);
2340         assert(align > 0);
2341
2342         if (message_end_of_array(m, *rindex))
2343                 return 0;
2344
2345         start = ALIGN_TO((size_t) *rindex, align);
2346         padding = start - *rindex;
2347         end = start + nbytes;
2348
2349         if (end > BUS_MESSAGE_BODY_SIZE(m))
2350                 return -EBADMSG;
2351
2352         part = find_part(m, *rindex, padding, (void**) &q);
2353         if (!part)
2354                 return -EBADMSG;
2355
2356         if (q) {
2357                 /* Verify padding */
2358                 for (k = 0; k < padding; k++)
2359                         if (q[k] != 0)
2360                                 return -EBADMSG;
2361         }
2362
2363         part = find_part(m, start, nbytes, (void**) &q);
2364         if (!part || !q)
2365                 return -EBADMSG;
2366
2367         *rindex = end;
2368
2369         if (ret)
2370                 *ret = q;
2371
2372         return 1;
2373 }
2374
2375 static bool validate_nul(const char *s, size_t l) {
2376
2377         /* Check for NUL chars in the string */
2378         if (memchr(s, 0, l))
2379                 return false;
2380
2381         /* Check for NUL termination */
2382         if (s[l] != 0)
2383                 return false;
2384
2385         return true;
2386 }
2387
2388 static bool validate_string(const char *s, size_t l) {
2389
2390         if (!validate_nul(s, l))
2391                 return false;
2392
2393         /* Check if valid UTF8 */
2394         if (!utf8_is_valid(s))
2395                 return false;
2396
2397         return true;
2398 }
2399
2400 static bool validate_signature(const char *s, size_t l) {
2401
2402         if (!validate_nul(s, l))
2403                 return false;
2404
2405         /* Check if valid signature */
2406         if (!signature_is_valid(s, true))
2407                 return false;
2408
2409         return true;
2410 }
2411
2412 static bool validate_object_path(const char *s, size_t l) {
2413
2414         if (!validate_nul(s, l))
2415                 return false;
2416
2417         if (!object_path_is_valid(s))
2418                 return false;
2419
2420         return true;
2421 }
2422
2423 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2424         struct bus_container *c;
2425         int r;
2426         void *q;
2427
2428         if (!m)
2429                 return -EINVAL;
2430         if (!m->sealed)
2431                 return -EPERM;
2432         if (!bus_type_is_basic(type))
2433                 return -EINVAL;
2434         if (!p)
2435                 return -EINVAL;
2436
2437         c = message_get_container(m);
2438
2439         if (!c->signature || c->signature[c->index] == 0)
2440                 return 0;
2441
2442         if (c->signature[c->index] != type)
2443                 return -ENXIO;
2444
2445         switch (type) {
2446
2447         case SD_BUS_TYPE_STRING:
2448         case SD_BUS_TYPE_OBJECT_PATH: {
2449                 uint32_t l;
2450                 size_t rindex;
2451
2452                 rindex = m->rindex;
2453                 r = message_peek_body(m, &rindex, 4, 4, &q);
2454                 if (r <= 0)
2455                         return r;
2456
2457                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2458                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2459                 if (r < 0)
2460                         return r;
2461                 if (r == 0)
2462                         return -EBADMSG;
2463
2464                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2465                         if (!validate_object_path(q, l))
2466                                 return -EBADMSG;
2467                 } else {
2468                         if (!validate_string(q, l))
2469                                 return -EBADMSG;
2470                 }
2471
2472                 m->rindex = rindex;
2473                 *(const char**) p = q;
2474                 break;
2475         }
2476
2477         case SD_BUS_TYPE_SIGNATURE: {
2478                 uint8_t l;
2479                 size_t rindex;
2480
2481                 rindex = m->rindex;
2482                 r = message_peek_body(m, &rindex, 1, 1, &q);
2483                 if (r <= 0)
2484                         return r;
2485
2486                 l = *(uint8_t*) q;
2487                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2488                 if (r < 0)
2489                         return r;
2490                 if (r == 0)
2491                         return -EBADMSG;
2492
2493                 if (!validate_signature(q, l))
2494                         return -EBADMSG;
2495
2496                 m->rindex = rindex;
2497                 *(const char**) p = q;
2498                 break;
2499         }
2500
2501         default: {
2502                 ssize_t sz, align;
2503                 size_t rindex;
2504
2505                 align = bus_type_get_alignment(type);
2506                 sz = bus_type_get_size(type);
2507                 assert(align > 0 && sz > 0);
2508
2509                 rindex = m->rindex;
2510                 r = message_peek_body(m, &rindex, align, sz, &q);
2511                 if (r <= 0)
2512                         return r;
2513
2514                 switch (type) {
2515
2516                 case SD_BUS_TYPE_BYTE:
2517                         *(uint8_t*) p = *(uint8_t*) q;
2518                         break;
2519
2520                 case SD_BUS_TYPE_BOOLEAN:
2521                         *(int*) p = !!*(uint32_t*) q;
2522                         break;
2523
2524                 case SD_BUS_TYPE_INT16:
2525                 case SD_BUS_TYPE_UINT16:
2526                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2527                         break;
2528
2529                 case SD_BUS_TYPE_INT32:
2530                 case SD_BUS_TYPE_UINT32:
2531                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2532                         break;
2533
2534                 case SD_BUS_TYPE_INT64:
2535                 case SD_BUS_TYPE_UINT64:
2536                 case SD_BUS_TYPE_DOUBLE:
2537                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2538                         break;
2539
2540                 case SD_BUS_TYPE_UNIX_FD: {
2541                         uint32_t j;
2542
2543                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2544                         if (j >= m->n_fds)
2545                                 return -EBADMSG;
2546
2547                         *(int*) p = m->fds[j];
2548                         break;
2549                 }
2550
2551                 default:
2552                         assert_not_reached("Unknown basic type...");
2553                 }
2554
2555                 m->rindex = rindex;
2556
2557                 break;
2558         }
2559         }
2560
2561         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2562                 c->index++;
2563
2564         return 1;
2565 }
2566
2567 static int bus_message_enter_array(
2568                 sd_bus_message *m,
2569                 struct bus_container *c,
2570                 const char *contents,
2571                 uint32_t **array_size) {
2572
2573         size_t rindex;
2574         void *q;
2575         int r, alignment;
2576
2577         assert(m);
2578         assert(c);
2579         assert(contents);
2580         assert(array_size);
2581
2582         if (!signature_is_single(contents))
2583                 return -EINVAL;
2584
2585         alignment = bus_type_get_alignment(contents[0]);
2586         if (alignment < 0)
2587                 return alignment;
2588
2589         if (!c->signature || c->signature[c->index] == 0)
2590                 return 0;
2591
2592         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2593                 return -ENXIO;
2594
2595         if (!startswith(c->signature + c->index + 1, contents))
2596                 return -ENXIO;
2597
2598         rindex = m->rindex;
2599         r = message_peek_body(m, &rindex, 4, 4, &q);
2600         if (r <= 0)
2601                 return r;
2602
2603         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2604                 return -EBADMSG;
2605
2606         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2607         if (r < 0)
2608                 return r;
2609         if (r == 0)
2610                 return -EBADMSG;
2611
2612         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2613                 c->index += 1 + strlen(contents);
2614
2615         m->rindex = rindex;
2616
2617         *array_size = (uint32_t*) q;
2618
2619         return 1;
2620 }
2621
2622 static int bus_message_enter_variant(
2623                 sd_bus_message *m,
2624                 struct bus_container *c,
2625                 const char *contents) {
2626
2627         size_t rindex;
2628         uint8_t l;
2629         void *q;
2630         int r;
2631
2632         assert(m);
2633         assert(c);
2634         assert(contents);
2635
2636         if (!signature_is_single(contents))
2637                 return -EINVAL;
2638
2639         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2640                 return -EINVAL;
2641
2642         if (!c->signature || c->signature[c->index] == 0)
2643                 return 0;
2644
2645         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2646                 return -ENXIO;
2647
2648         rindex = m->rindex;
2649         r = message_peek_body(m, &rindex, 1, 1, &q);
2650         if (r <= 0)
2651                 return r;
2652
2653         l = *(uint8_t*) q;
2654         r = message_peek_body(m, &rindex, 1, l+1, &q);
2655         if (r < 0)
2656                 return r;
2657         if (r == 0)
2658                 return -EBADMSG;
2659
2660         if (!validate_signature(q, l))
2661                 return -EBADMSG;
2662
2663         if (!streq(q, contents))
2664                 return -ENXIO;
2665
2666         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2667                 c->index++;
2668
2669         m->rindex = rindex;
2670
2671         return 1;
2672 }
2673
2674 static int bus_message_enter_struct(
2675                 sd_bus_message *m,
2676                 struct bus_container *c,
2677                 const char *contents) {
2678
2679         size_t l;
2680         int r;
2681
2682         assert(m);
2683         assert(c);
2684         assert(contents);
2685
2686         if (!signature_is_valid(contents, false))
2687                 return -EINVAL;
2688
2689         if (!c->signature || c->signature[c->index] == 0)
2690                 return 0;
2691
2692         l = strlen(contents);
2693
2694         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2695             !startswith(c->signature + c->index + 1, contents) ||
2696             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2697                 return -ENXIO;
2698
2699         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2700         if (r <= 0)
2701                 return r;
2702
2703         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2704                 c->index += 1 + l + 1;
2705
2706         return 1;
2707 }
2708
2709 static int bus_message_enter_dict_entry(
2710                 sd_bus_message *m,
2711                 struct bus_container *c,
2712                 const char *contents) {
2713
2714         size_t l;
2715         int r;
2716
2717         assert(m);
2718         assert(c);
2719         assert(contents);
2720
2721         if (!signature_is_pair(contents))
2722                 return -EINVAL;
2723
2724         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2725                 return -ENXIO;
2726
2727         if (!c->signature || c->signature[c->index] == 0)
2728                 return 0;
2729
2730         l = strlen(contents);
2731
2732         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2733             !startswith(c->signature + c->index + 1, contents) ||
2734             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2735                 return -ENXIO;
2736
2737         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2738         if (r <= 0)
2739                 return r;
2740
2741         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2742                 c->index += 1 + l + 1;
2743
2744         return 1;
2745 }
2746
2747 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2748         struct bus_container *c, *w;
2749         uint32_t *array_size = NULL;
2750         char *signature;
2751         size_t before;
2752         int r;
2753
2754         if (!m)
2755                 return -EINVAL;
2756         if (!m->sealed)
2757                 return -EPERM;
2758         if (!contents)
2759                 return -EINVAL;
2760
2761         /*
2762          * We enforce a global limit on container depth, that is much
2763          * higher than the 32 structs and 32 arrays the specification
2764          * mandates. This is simpler to implement for us, and we need
2765          * this only to ensure our container array doesn't grow
2766          * without bounds. We are happy to return any data from a
2767          * message as long as the data itself is valid, even if the
2768          * overall message might be not.
2769          *
2770          * Note that the message signature is validated when
2771          * parsing the headers, and that validation does check the
2772          * 32/32 limit.
2773          *
2774          * Note that the specification defines no limits on the depth
2775          * of stacked variants, but we do.
2776          */
2777         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2778                 return -EBADMSG;
2779
2780         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2781         if (!w)
2782                 return -ENOMEM;
2783         m->containers = w;
2784
2785         c = message_get_container(m);
2786
2787         if (!c->signature || c->signature[c->index] == 0)
2788                 return 0;
2789
2790         signature = strdup(contents);
2791         if (!signature)
2792                 return -ENOMEM;
2793
2794         c->saved_index = c->index;
2795         before = m->rindex;
2796
2797         if (type == SD_BUS_TYPE_ARRAY)
2798                 r = bus_message_enter_array(m, c, contents, &array_size);
2799         else if (type == SD_BUS_TYPE_VARIANT)
2800                 r = bus_message_enter_variant(m, c, contents);
2801         else if (type == SD_BUS_TYPE_STRUCT)
2802                 r = bus_message_enter_struct(m, c, contents);
2803         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2804                 r = bus_message_enter_dict_entry(m, c, contents);
2805         else
2806                 r = -EINVAL;
2807
2808         if (r <= 0) {
2809                 free(signature);
2810                 return r;
2811         }
2812
2813         /* OK, let's fill it in */
2814         w += m->n_containers++;
2815         w->enclosing = type;
2816         w->signature = signature;
2817         w->index = 0;
2818         w->array_size = array_size;
2819         w->before = before;
2820         w->begin = m->rindex;
2821
2822         return 1;
2823 }
2824
2825 int sd_bus_message_exit_container(sd_bus_message *m) {
2826         struct bus_container *c;
2827
2828         if (!m)
2829                 return -EINVAL;
2830         if (!m->sealed)
2831                 return -EPERM;
2832         if (m->n_containers <= 0)
2833                 return -EINVAL;
2834
2835         c = message_get_container(m);
2836         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2837                 uint32_t l;
2838
2839                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2840                 if (c->begin + l != m->rindex)
2841                         return -EBUSY;
2842
2843         } else {
2844                 if (c->signature && c->signature[c->index] != 0)
2845                         return -EINVAL;
2846         }
2847
2848         free(c->signature);
2849         m->n_containers--;
2850
2851         return 1;
2852 }
2853
2854 static void message_quit_container(sd_bus_message *m) {
2855         struct bus_container *c;
2856
2857         assert(m);
2858         assert(m->sealed);
2859         assert(m->n_containers > 0);
2860
2861         c = message_get_container(m);
2862
2863         /* Undo seeks */
2864         assert(m->rindex >= c->before);
2865         m->rindex = c->before;
2866
2867         /* Free container */
2868         free(c->signature);
2869         m->n_containers--;
2870
2871         /* Correct index of new top-level container */
2872         c = message_get_container(m);
2873         c->index = c->saved_index;
2874 }
2875
2876 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2877         struct bus_container *c;
2878         int r;
2879
2880         if (!m)
2881                 return -EINVAL;
2882         if (!m->sealed)
2883                 return -EPERM;
2884
2885         c = message_get_container(m);
2886
2887         if (!c->signature || c->signature[c->index] == 0)
2888                 goto eof;
2889
2890         if (message_end_of_array(m, m->rindex))
2891                 goto eof;
2892
2893         if (bus_type_is_basic(c->signature[c->index])) {
2894                 if (contents)
2895                         *contents = NULL;
2896                 if (type)
2897                         *type = c->signature[c->index];
2898                 return 1;
2899         }
2900
2901         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2902
2903                 if (contents) {
2904                         size_t l;
2905                         char *sig;
2906
2907                         r = signature_element_length(c->signature+c->index+1, &l);
2908                         if (r < 0)
2909                                 return r;
2910
2911                         assert(l >= 1);
2912
2913                         sig = strndup(c->signature + c->index + 1, l);
2914                         if (!sig)
2915                                 return -ENOMEM;
2916
2917                         free(m->peeked_signature);
2918                         m->peeked_signature = sig;
2919
2920                         *contents = sig;
2921                 }
2922
2923                 if (type)
2924                         *type = SD_BUS_TYPE_ARRAY;
2925
2926                 return 1;
2927         }
2928
2929         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2930             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2931
2932                 if (contents) {
2933                         size_t l;
2934                         char *sig;
2935
2936                         r = signature_element_length(c->signature+c->index, &l);
2937                         if (r < 0)
2938                                 return r;
2939
2940                         assert(l >= 2);
2941                         sig = strndup(c->signature + c->index + 1, l - 2);
2942                         if (!sig)
2943                                 return -ENOMEM;
2944
2945                         free(m->peeked_signature);
2946                         m->peeked_signature = sig;
2947
2948                         *contents = sig;
2949                 }
2950
2951                 if (type)
2952                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2953
2954                 return 1;
2955         }
2956
2957         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2958                 if (contents) {
2959                         size_t rindex, l;
2960                         void *q;
2961
2962                         rindex = m->rindex;
2963                         r = message_peek_body(m, &rindex, 1, 1, &q);
2964                         if (r < 0)
2965                                 return r;
2966                         if (r == 0)
2967                                 goto eof;
2968
2969                         l = *(uint8_t*) q;
2970                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2971                         if (r < 0)
2972                                 return r;
2973                         if (r == 0)
2974                                 return -EBADMSG;
2975
2976                         if (!validate_signature(q, l))
2977                                 return -EBADMSG;
2978
2979                         *contents = q;
2980                 }
2981
2982                 if (type)
2983                         *type = SD_BUS_TYPE_VARIANT;
2984
2985                 return 1;
2986         }
2987
2988         return -EINVAL;
2989
2990 eof:
2991         if (type)
2992                 *type = c->enclosing;
2993         if (contents)
2994                 *contents = NULL;
2995         return 0;
2996 }
2997
2998 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2999         struct bus_container *c;
3000
3001         if (!m)
3002                 return -EINVAL;
3003         if (!m->sealed)
3004                 return -EPERM;
3005
3006         if (complete) {
3007                 message_reset_containers(m);
3008                 m->rindex = 0;
3009                 m->root_container.index = 0;
3010
3011                 c = message_get_container(m);
3012         } else {
3013                 c = message_get_container(m);
3014
3015                 c->index = 0;
3016                 m->rindex = c->begin;
3017         }
3018
3019         return !isempty(c->signature);
3020 }
3021 static int message_read_ap(
3022                 sd_bus_message *m,
3023                 const char *types,
3024                 va_list ap) {
3025
3026         unsigned n_array, n_struct;
3027         TypeStack stack[BUS_CONTAINER_DEPTH];
3028         unsigned stack_ptr = 0;
3029         int r;
3030
3031         assert(m);
3032
3033         if (!types)
3034                 return 0;
3035
3036         /* Ideally, we'd just call ourselves recursively on every
3037          * complex type. However, the state of a va_list that is
3038          * passed to a function is undefined after that function
3039          * returns. This means we need to docode the va_list linearly
3040          * in a single stackframe. We hence implement our own
3041          * home-grown stack in an array. */
3042
3043         n_array = (unsigned) -1;
3044         n_struct = strlen(types);
3045
3046         for (;;) {
3047                 const char *t;
3048
3049                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3050                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3051                         if (r < 0)
3052                                 return r;
3053                         if (r == 0)
3054                                 break;
3055
3056                         r = sd_bus_message_exit_container(m);
3057                         if (r < 0)
3058                                 return r;
3059
3060                         continue;
3061                 }
3062
3063                 t = types;
3064                 if (n_array != (unsigned) -1)
3065                         n_array --;
3066                 else {
3067                         types ++;
3068                         n_struct--;
3069                 }
3070
3071                 switch (*t) {
3072
3073                 case SD_BUS_TYPE_BYTE:
3074                 case SD_BUS_TYPE_BOOLEAN:
3075                 case SD_BUS_TYPE_INT16:
3076                 case SD_BUS_TYPE_UINT16:
3077                 case SD_BUS_TYPE_INT32:
3078                 case SD_BUS_TYPE_UINT32:
3079                 case SD_BUS_TYPE_INT64:
3080                 case SD_BUS_TYPE_UINT64:
3081                 case SD_BUS_TYPE_DOUBLE:
3082                 case SD_BUS_TYPE_STRING:
3083                 case SD_BUS_TYPE_OBJECT_PATH:
3084                 case SD_BUS_TYPE_SIGNATURE:
3085                 case SD_BUS_TYPE_UNIX_FD: {
3086                         void *p;
3087
3088                         p = va_arg(ap, void*);
3089                         r = sd_bus_message_read_basic(m, *t, p);
3090                         if (r < 0)
3091                                 return r;
3092                         if (r == 0)
3093                                 return -ENXIO;
3094
3095                         break;
3096                 }
3097
3098                 case SD_BUS_TYPE_ARRAY: {
3099                         size_t k;
3100
3101                         r = signature_element_length(t + 1, &k);
3102                         if (r < 0)
3103                                 return r;
3104
3105                         {
3106                                 char s[k + 1];
3107                                 memcpy(s, t + 1, k);
3108                                 s[k] = 0;
3109
3110                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3111                                 if (r < 0)
3112                                         return r;
3113                                 if (r == 0)
3114                                         return -ENXIO;
3115                         }
3116
3117                         if (n_array == (unsigned) -1) {
3118                                 types += k;
3119                                 n_struct -= k;
3120                         }
3121
3122                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3123                         if (r < 0)
3124                                 return r;
3125
3126                         types = t + 1;
3127                         n_struct = k;
3128                         n_array = va_arg(ap, unsigned);
3129
3130                         break;
3131                 }
3132
3133                 case SD_BUS_TYPE_VARIANT: {
3134                         const char *s;
3135
3136                         s = va_arg(ap, const char *);
3137                         if (!s)
3138                                 return -EINVAL;
3139
3140                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3141                         if (r < 0)
3142                                 return r;
3143                         if (r == 0)
3144                                 return -ENXIO;
3145
3146                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3147                         if (r < 0)
3148                                 return r;
3149
3150                         types = s;
3151                         n_struct = strlen(s);
3152                         n_array = (unsigned) -1;
3153
3154                         break;
3155                 }
3156
3157                 case SD_BUS_TYPE_STRUCT_BEGIN:
3158                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3159                         size_t k;
3160
3161                         r = signature_element_length(t, &k);
3162                         if (r < 0)
3163                                 return r;
3164
3165                         {
3166                                 char s[k - 1];
3167                                 memcpy(s, t + 1, k - 2);
3168                                 s[k - 2] = 0;
3169
3170                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3171                                 if (r < 0)
3172                                         return r;
3173                                 if (r == 0)
3174                                         return -ENXIO;
3175                         }
3176
3177                         if (n_array == (unsigned) -1) {
3178                                 types += k - 1;
3179                                 n_struct -= k - 1;
3180                         }
3181
3182                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3183                         if (r < 0)
3184                                 return r;
3185
3186                         types = t + 1;
3187                         n_struct = k - 2;
3188                         n_array = (unsigned) -1;
3189
3190                         break;
3191                 }
3192
3193                 default:
3194                         return -EINVAL;
3195                 }
3196         }
3197
3198         return 1;
3199 }
3200
3201 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3202         va_list ap;
3203         int r;
3204
3205         if (!m)
3206                 return -EINVAL;
3207         if (!m->sealed)
3208                 return -EPERM;
3209         if (!types)
3210                 return -EINVAL;
3211
3212         va_start(ap, types);
3213         r = message_read_ap(m, types, ap);
3214         va_end(ap);
3215
3216         return r;
3217 }
3218
3219 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3220         struct bus_container *c;
3221         void *p;
3222         size_t sz;
3223         ssize_t align;
3224         int r;
3225
3226         if (!m)
3227                 return -EINVAL;
3228         if (!m->sealed)
3229                 return -EPERM;
3230         if (!bus_type_is_trivial(type))
3231                 return -EINVAL;
3232         if (!ptr)
3233                 return -EINVAL;
3234         if (!size)
3235                 return -EINVAL;
3236         if (BUS_MESSAGE_NEED_BSWAP(m))
3237                 return -ENOTSUP;
3238
3239         align = bus_type_get_alignment(type);
3240         if (align < 0)
3241                 return align;
3242
3243         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3244         if (r <= 0)
3245                 return r;
3246
3247         c = message_get_container(m);
3248         sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3249
3250         r = message_peek_body(m, &m->rindex, align, sz, &p);
3251         if (r < 0)
3252                 goto fail;
3253         if (r == 0) {
3254                 r = -EBADMSG;
3255                 goto fail;
3256         }
3257
3258         r = sd_bus_message_exit_container(m);
3259         if (r < 0)
3260                 goto fail;
3261
3262         *ptr = (const void*) p;
3263         *size = sz;
3264
3265         return 1;
3266
3267 fail:
3268         message_quit_container(m);
3269         return r;
3270 }
3271
3272 static int message_peek_fields(
3273                 sd_bus_message *m,
3274                 size_t *rindex,
3275                 size_t align,
3276                 size_t nbytes,
3277                 void **ret) {
3278
3279         assert(m);
3280         assert(rindex);
3281         assert(align > 0);
3282
3283         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3284 }
3285
3286 static int message_peek_field_uint32(
3287                 sd_bus_message *m,
3288                 size_t *ri,
3289                 uint32_t *ret) {
3290
3291         int r;
3292         void *q;
3293
3294         assert(m);
3295         assert(ri);
3296
3297         r = message_peek_fields(m, ri, 4, 4, &q);
3298         if (r < 0)
3299                 return r;
3300
3301         if (ret)
3302                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3303
3304         return 0;
3305 }
3306
3307 static int message_peek_field_string(
3308                 sd_bus_message *m,
3309                 bool (*validate)(const char *p),
3310                 size_t *ri,
3311                 const char **ret) {
3312
3313         uint32_t l;
3314         int r;
3315         void *q;
3316
3317         assert(m);
3318         assert(ri);
3319
3320         r = message_peek_field_uint32(m, ri, &l);
3321         if (r < 0)
3322                 return r;
3323
3324         r = message_peek_fields(m, ri, 1, l+1, &q);
3325         if (r < 0)
3326                 return r;
3327
3328         if (validate) {
3329                 if (!validate_nul(q, l))
3330                         return -EBADMSG;
3331
3332                 if (!validate(q))
3333                         return -EBADMSG;
3334         } else {
3335                 if (!validate_string(q, l))
3336                         return -EBADMSG;
3337         }
3338
3339         if (ret)
3340                 *ret = q;
3341
3342         return 0;
3343 }
3344
3345 static int message_peek_field_signature(
3346                 sd_bus_message *m,
3347                 size_t *ri,
3348                 const char **ret) {
3349
3350         size_t l;
3351         int r;
3352         void *q;
3353
3354         assert(m);
3355         assert(ri);
3356
3357         r = message_peek_fields(m, ri, 1, 1, &q);
3358         if (r < 0)
3359                 return r;
3360
3361         l = *(uint8_t*) q;
3362         r = message_peek_fields(m, ri, 1, l+1, &q);
3363         if (r < 0)
3364                 return r;
3365
3366         if (!validate_signature(q, l))
3367                 return -EBADMSG;
3368
3369         if (ret)
3370                 *ret = q;
3371
3372         return 0;
3373 }
3374
3375 static int message_skip_fields(
3376                 sd_bus_message *m,
3377                 size_t *ri,
3378                 uint32_t array_size,
3379                 const char **signature) {
3380
3381         size_t original_index;
3382         int r;
3383
3384         assert(m);
3385         assert(ri);
3386         assert(signature);
3387
3388         original_index = *ri;
3389
3390         for (;;) {
3391                 char t;
3392                 size_t l;
3393
3394                 if (array_size != (uint32_t) -1 &&
3395                     array_size <= *ri - original_index)
3396                         return 0;
3397
3398                 t = **signature;
3399                 if (!t)
3400                         return 0;
3401
3402                 if (t == SD_BUS_TYPE_STRING) {
3403
3404                         r = message_peek_field_string(m, NULL, ri, NULL);
3405                         if (r < 0)
3406                                 return r;
3407
3408                         (*signature)++;
3409
3410                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3411
3412                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3413                         if (r < 0)
3414                                 return r;
3415
3416                         (*signature)++;
3417
3418                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3419
3420                         r = message_peek_field_signature(m, ri, NULL);
3421                         if (r < 0)
3422                                 return r;
3423
3424                         (*signature)++;
3425
3426                 } else if (bus_type_is_basic(t)) {
3427                         ssize_t align, k;
3428
3429                         align = bus_type_get_alignment(t);
3430                         k = bus_type_get_size(t);
3431                         assert(align > 0 && k > 0);
3432
3433                         r = message_peek_fields(m, ri, align, k, NULL);
3434                         if (r < 0)
3435                                 return r;
3436
3437                         (*signature)++;
3438
3439                 } else if (t == SD_BUS_TYPE_ARRAY) {
3440
3441                         r = signature_element_length(*signature+1, &l);
3442                         if (r < 0)
3443                                 return r;
3444
3445                         assert(l >= 1);
3446                         {
3447                                 char sig[l-1], *s;
3448                                 uint32_t nas;
3449                                 int alignment;
3450
3451                                 strncpy(sig, *signature + 1, l-1);
3452                                 s = sig;
3453
3454                                 alignment = bus_type_get_alignment(sig[0]);
3455                                 if (alignment < 0)
3456                                         return alignment;
3457
3458                                 r = message_peek_field_uint32(m, ri, &nas);
3459                                 if (r < 0)
3460                                         return r;
3461                                 if (nas > BUS_ARRAY_MAX_SIZE)
3462                                         return -EBADMSG;
3463
3464                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
3465                                 if (r < 0)
3466                                         return r;
3467
3468                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
3469                                 if (r < 0)
3470                                         return r;
3471                         }
3472
3473                         (*signature) += 1 + l;
3474
3475                 } else if (t == SD_BUS_TYPE_VARIANT) {
3476                         const char *s;
3477
3478                         r = message_peek_field_signature(m, ri, &s);
3479                         if (r < 0)
3480                                 return r;
3481
3482                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3483                         if (r < 0)
3484                                 return r;
3485
3486                         (*signature)++;
3487
3488                 } else if (t == SD_BUS_TYPE_STRUCT ||
3489                            t == SD_BUS_TYPE_DICT_ENTRY) {
3490
3491                         r = signature_element_length(*signature, &l);
3492                         if (r < 0)
3493                                 return r;
3494
3495                         assert(l >= 2);
3496                         {
3497                                 char sig[l-1], *s;
3498                                 strncpy(sig, *signature + 1, l-1);
3499                                 s = sig;
3500
3501                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3502                                 if (r < 0)
3503                                         return r;
3504                         }
3505
3506                         *signature += l;
3507                 } else
3508                         return -EINVAL;
3509         }
3510 }
3511
3512 int bus_message_parse_fields(sd_bus_message *m) {
3513         size_t ri;
3514         int r;
3515         uint32_t unix_fds = 0;
3516
3517         assert(m);
3518
3519         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3520                 const char *signature;
3521                 uint8_t *header;
3522
3523                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3524                 if (r < 0)
3525                         return r;
3526
3527                 r = message_peek_field_signature(m, &ri, &signature);
3528                 if (r < 0)
3529                         return r;
3530
3531                 switch (*header) {
3532                 case _SD_BUS_MESSAGE_HEADER_INVALID:
3533                         return -EBADMSG;
3534
3535                 case SD_BUS_MESSAGE_HEADER_PATH:
3536
3537                         if (m->path)
3538                                 return -EBADMSG;
3539
3540                         if (!streq(signature, "o"))
3541                                 return -EBADMSG;
3542
3543                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3544                         break;
3545
3546                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3547
3548                         if (m->interface)
3549                                 return -EBADMSG;
3550
3551                         if (!streq(signature, "s"))
3552                                 return -EBADMSG;
3553
3554                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3555                         break;
3556
3557                 case SD_BUS_MESSAGE_HEADER_MEMBER:
3558
3559                         if (m->member)
3560                                 return -EBADMSG;
3561
3562                         if (!streq(signature, "s"))
3563                                 return -EBADMSG;
3564
3565                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3566                         break;
3567
3568                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3569
3570                         if (m->error.name)
3571                                 return -EBADMSG;
3572
3573                         if (!streq(signature, "s"))
3574                                 return -EBADMSG;
3575
3576                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3577                         break;
3578
3579                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3580
3581                         if (m->destination)
3582                                 return -EBADMSG;
3583
3584                         if (!streq(signature, "s"))
3585                                 return -EBADMSG;
3586
3587                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3588                         break;
3589
3590                 case SD_BUS_MESSAGE_HEADER_SENDER:
3591
3592                         if (m->sender)
3593                                 return -EBADMSG;
3594
3595                         if (!streq(signature, "s"))
3596                                 return -EBADMSG;
3597
3598                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3599                         break;
3600
3601
3602                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3603                         const char *s;
3604                         char *c;
3605
3606                         if (m->root_container.signature)
3607                                 return -EBADMSG;
3608
3609                         if (!streq(signature, "g"))
3610                                 return -EBADMSG;
3611
3612                         r = message_peek_field_signature(m, &ri, &s);
3613                         if (r < 0)
3614                                 return r;
3615
3616                         c = strdup(s);
3617                         if (!c)
3618                                 return -ENOMEM;
3619
3620                         free(m->root_container.signature);
3621                         m->root_container.signature = c;
3622                         break;
3623                 }
3624
3625                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3626                         if (m->reply_serial != 0)
3627                                 return -EBADMSG;
3628
3629                         if (!streq(signature, "u"))
3630                                 return -EBADMSG;
3631
3632                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3633                         if (r < 0)
3634                                 return r;
3635
3636                         if (m->reply_serial == 0)
3637                                 return -EBADMSG;
3638
3639                         break;
3640
3641                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3642                         if (unix_fds != 0)
3643                                 return -EBADMSG;
3644
3645                         if (!streq(signature, "u"))
3646                                 return -EBADMSG;
3647
3648                         r = message_peek_field_uint32(m, &ri, &unix_fds);
3649                         if (r < 0)
3650                                 return -EBADMSG;
3651
3652                         if (unix_fds == 0)
3653                                 return -EBADMSG;
3654
3655                         break;
3656
3657                 default:
3658                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3659                 }
3660
3661                 if (r < 0)
3662                         return r;
3663         }
3664
3665         if (m->n_fds != unix_fds)
3666                 return -EBADMSG;
3667
3668         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3669                 return -EBADMSG;
3670
3671         switch (m->header->type) {
3672
3673         case SD_BUS_MESSAGE_TYPE_SIGNAL:
3674                 if (!m->path || !m->interface || !m->member)
3675                         return -EBADMSG;
3676                 break;
3677
3678         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
3679
3680                 if (!m->path || !m->member)
3681                         return -EBADMSG;
3682
3683                 break;
3684
3685         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
3686
3687                 if (m->reply_serial == 0)
3688                         return -EBADMSG;
3689                 break;
3690
3691         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
3692
3693                 if (m->reply_serial == 0 || !m->error.name)
3694                         return -EBADMSG;
3695                 break;
3696         }
3697
3698         /* Try to read the error message, but if we can't it's a non-issue */
3699         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
3700                 sd_bus_message_read(m, "s", &m->error.message);
3701
3702         return 0;
3703 }
3704
3705 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3706         struct bus_body_part *part;
3707         size_t l, a;
3708         unsigned i;
3709         int r;
3710
3711         assert(m);
3712
3713         if (m->sealed)
3714                 return -EPERM;
3715
3716         if (m->n_containers > 0)
3717                 return -EBADMSG;
3718
3719         if (m->poisoned)
3720                 return -ESTALE;
3721
3722         /* If there's a non-trivial signature set, then add it in here */
3723         if (!isempty(m->root_container.signature)) {
3724                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3725                 if (r < 0)
3726                         return r;
3727         }
3728
3729         if (m->n_fds > 0) {
3730                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3731                 if (r < 0)
3732                         return r;
3733         }
3734
3735         /* Add padding at the end of the fields part, since we know
3736          * the body needs to start at an 8 byte alignment. We made
3737          * sure we allocated enough space for this, so all we need to
3738          * do here is to zero it out. */
3739         l = BUS_MESSAGE_FIELDS_SIZE(m);
3740         a = ALIGN8(l) - l;
3741         if (a > 0)
3742                 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3743
3744         /* If this is something we can send as memfd, then let's seal
3745         the memfd now. Note that we can send memfds as payload only
3746         for directed messages, and not for broadcasts. */
3747         if (m->destination) {
3748                 MESSAGE_FOREACH_PART(part, i, m)
3749                         if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) {
3750                                 bus_body_part_unmap(part);
3751
3752                                 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3753                                         part->sealed = true;
3754                         }
3755         }
3756
3757         m->header->serial = serial;
3758         m->sealed = true;
3759
3760         return 0;
3761 }
3762
3763 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3764         if (!m)
3765                 return -EINVAL;
3766         if (!destination)
3767                 return -EINVAL;
3768         if (m->sealed)
3769                 return -EPERM;
3770         if (m->destination)
3771                 return -EEXIST;
3772
3773         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
3774 }
3775
3776 int bus_message_dump(sd_bus_message *m) {
3777         const char *u = NULL, *uu = NULL, *s = NULL;
3778         char **cmdline = NULL;
3779         unsigned level = 1;
3780         int r;
3781         uid_t owner, audit_loginuid;
3782         uint32_t audit_sessionid;
3783
3784         assert(m);
3785
3786         printf("Message %p\n"
3787                "\tn_ref=%u\n"
3788                "\tendian=%c\n"
3789                "\ttype=%i\n"
3790                "\tflags=%u\n"
3791                "\tversion=%u\n"
3792                "\tserial=%u\n"
3793                "\tfields_size=%u\n"
3794                "\tbody_size=%u\n"
3795                "\tpath=%s\n"
3796                "\tinterface=%s\n"
3797                "\tmember=%s\n"
3798                "\tdestination=%s\n"
3799                "\tsender=%s\n"
3800                "\tsignature=%s\n"
3801                "\treply_serial=%u\n"
3802                "\terror.name=%s\n"
3803                "\terror.message=%s\n"
3804                "\tsealed=%s\n"
3805                "\tn_body_parts=%u\n",
3806                m,
3807                m->n_ref,
3808                m->header->endian,
3809                m->header->type,
3810                m->header->flags,
3811                m->header->version,
3812                BUS_MESSAGE_SERIAL(m),
3813                BUS_MESSAGE_FIELDS_SIZE(m),
3814                BUS_MESSAGE_BODY_SIZE(m),
3815                strna(m->path),
3816                strna(m->interface),
3817                strna(m->member),
3818                strna(m->destination),
3819                strna(m->sender),
3820                strna(m->root_container.signature),
3821                m->reply_serial,
3822                strna(m->error.name),
3823                strna(m->error.message),
3824                yes_no(m->sealed),
3825                m->n_body_parts);
3826
3827         if (m->pid != 0)
3828                 printf("\tpid=%lu\n", (unsigned long) m->pid);
3829         if (m->tid != 0)
3830                 printf("\ttid=%lu\n", (unsigned long) m->tid);
3831         if (m->uid_valid)
3832                 printf("\tuid=%lu\n", (unsigned long) m->uid);
3833         if (m->gid_valid)
3834                 printf("\tgid=%lu\n", (unsigned long) m->gid);
3835         if (m->pid_starttime != 0)
3836                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
3837         if (m->monotonic != 0)
3838                 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
3839         if (m->realtime != 0)
3840                 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
3841         if (m->exe)
3842                 printf("\texe=[%s]\n", m->exe);
3843         if (m->comm)
3844                 printf("\tcomm=[%s]\n", m->comm);
3845         if (m->tid_comm)
3846                 printf("\ttid_comm=[%s]\n", m->tid_comm);
3847         if (m->label)
3848                 printf("\tlabel=[%s]\n", m->label);
3849         if (m->cgroup)
3850                 printf("\tcgroup=[%s]\n", m->cgroup);
3851
3852         sd_bus_message_get_unit(m, &u);
3853         if (u)
3854                 printf("\tunit=[%s]\n", u);
3855         sd_bus_message_get_user_unit(m, &uu);
3856         if (uu)
3857                 printf("\tuser_unit=[%s]\n", uu);
3858         sd_bus_message_get_session(m, &s);
3859         if (s)
3860                 printf("\tsession=[%s]\n", s);
3861         if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
3862                 printf("\towner_uid=%lu\n", (unsigned long) owner);
3863         if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
3864                 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
3865         if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
3866                 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
3867
3868         printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
3869
3870         if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
3871                 char **c;
3872
3873                 fputs("\tcmdline=[", stdout);
3874                 STRV_FOREACH(c, cmdline) {
3875                         if (c != cmdline)
3876                                 putchar(' ');
3877
3878                         fputs(*c, stdout);
3879                 }
3880
3881                 fputs("]\n", stdout);
3882         }
3883
3884         r = sd_bus_message_rewind(m, true);
3885         if (r < 0) {
3886                 log_error("Failed to rewind: %s", strerror(-r));
3887                 return r;
3888         }
3889
3890         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3891
3892         for(;;) {
3893                 _cleanup_free_ char *prefix = NULL;
3894                 const char *contents = NULL;
3895                 char type;
3896                 union {
3897                         uint8_t u8;
3898                         uint16_t u16;
3899                         int16_t s16;
3900                         uint32_t u32;
3901                         int32_t s32;
3902                         uint64_t u64;
3903                         int64_t s64;
3904                         double d64;
3905                         const char *string;
3906                         int i;
3907                 } basic;
3908
3909                 r = sd_bus_message_peek_type(m, &type, &contents);
3910                 if (r < 0) {
3911                         log_error("Failed to peek type: %s", strerror(-r));
3912                         return r;
3913                 }
3914                 if (r == 0) {
3915                         if (level <= 1)
3916                                 break;
3917
3918                         r = sd_bus_message_exit_container(m);
3919                         if (r < 0) {
3920                                 log_error("Failed to exit container: %s", strerror(-r));
3921                                 return r;
3922                         }
3923
3924                         level--;
3925
3926                         prefix = strrep("\t", level);
3927                         if (!prefix)
3928                                 return log_oom();
3929
3930                         if (type == SD_BUS_TYPE_ARRAY)
3931                                 printf("%s} END_ARRAY \n", prefix);
3932                         else if (type == SD_BUS_TYPE_VARIANT)
3933                                 printf("%s} END_VARIANT\n", prefix);
3934                         else if (type == SD_BUS_TYPE_STRUCT)
3935                                 printf("%s} END_STRUCT\n", prefix);
3936                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3937                                 printf("%s} END_DICT_ENTRY\n", prefix);
3938
3939                         continue;
3940                 }
3941
3942                 prefix = strrep("\t", level);
3943                 if (!prefix)
3944                         return log_oom();
3945
3946                 if (bus_type_is_container(type) > 0) {
3947                         r = sd_bus_message_enter_container(m, type, contents);
3948                         if (r < 0) {
3949                                 log_error("Failed to enter container: %s", strerror(-r));
3950                                 return r;
3951                         }
3952
3953                         if (type == SD_BUS_TYPE_ARRAY)
3954                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
3955                         else if (type == SD_BUS_TYPE_VARIANT)
3956                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3957                         else if (type == SD_BUS_TYPE_STRUCT)
3958                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3959                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3960                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3961
3962                         level ++;
3963
3964                         continue;
3965                 }
3966
3967                 r = sd_bus_message_read_basic(m, type, &basic);
3968                 if (r < 0) {
3969                         log_error("Failed to get basic: %s", strerror(-r));
3970                         return r;
3971                 }
3972
3973                 switch (type) {
3974
3975                 case SD_BUS_TYPE_BYTE:
3976                         printf("%sBYTE: %u\n", prefix, basic.u8);
3977                         break;
3978
3979                 case SD_BUS_TYPE_BOOLEAN:
3980                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3981                         break;
3982
3983                 case SD_BUS_TYPE_INT16:
3984                         printf("%sINT16: %i\n", prefix, basic.s16);
3985                         break;
3986
3987                 case SD_BUS_TYPE_UINT16:
3988                         printf("%sUINT16: %u\n", prefix, basic.u16);
3989                         break;
3990
3991                 case SD_BUS_TYPE_INT32:
3992                         printf("%sINT32: %i\n", prefix, basic.s32);
3993                         break;
3994
3995                 case SD_BUS_TYPE_UINT32:
3996                         printf("%sUINT32: %u\n", prefix, basic.u32);
3997                         break;
3998
3999                 case SD_BUS_TYPE_INT64:
4000                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4001                         break;
4002
4003                 case SD_BUS_TYPE_UINT64:
4004                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4005                         break;
4006
4007                 case SD_BUS_TYPE_DOUBLE:
4008                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
4009                         break;
4010
4011                 case SD_BUS_TYPE_STRING:
4012                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4013                         break;
4014
4015                 case SD_BUS_TYPE_OBJECT_PATH:
4016                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4017                         break;
4018
4019                 case SD_BUS_TYPE_SIGNATURE:
4020                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4021                         break;
4022
4023                 case SD_BUS_TYPE_UNIX_FD:
4024                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
4025                         break;
4026
4027                 default:
4028                         assert_not_reached("Unknown basic type.");
4029                 }
4030         }
4031
4032         printf("} END_MESSAGE\n");
4033         return 0;
4034 }
4035
4036 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4037         size_t total;
4038         void *p, *e;
4039         unsigned i;
4040         struct bus_body_part *part;
4041
4042         assert(m);
4043         assert(buffer);
4044         assert(sz);
4045
4046         total = BUS_MESSAGE_SIZE(m);
4047
4048         p = malloc(total);
4049         if (!p)
4050                 return -ENOMEM;
4051
4052         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4053         MESSAGE_FOREACH_PART(part, i, m)
4054                 e = mempcpy(e, part->data, part->size);
4055
4056         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4057
4058         *buffer = p;
4059         *sz = total;
4060
4061         return 0;
4062 }
4063
4064 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4065         int r;
4066
4067         assert(m);
4068         assert(l);
4069
4070         r = sd_bus_message_enter_container(m, 'a', "s");
4071         if (r < 0)
4072                 return r;
4073
4074         for (;;) {
4075                 const char *s;
4076
4077                 r = sd_bus_message_read_basic(m, 's', &s);
4078                 if (r < 0)
4079                         return r;
4080                 if (r == 0)
4081                         break;
4082
4083                 r = strv_extend(l, s);
4084                 if (r < 0)
4085                         return r;
4086         }
4087
4088         r = sd_bus_message_exit_container(m);
4089         if (r < 0)
4090                 return r;
4091
4092         return 0;
4093 }
4094
4095 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4096         int r;
4097         const char *t = NULL;
4098         unsigned j;
4099
4100         assert(m);
4101
4102         r = sd_bus_message_rewind(m, true);
4103         if (r < 0)
4104                 return NULL;
4105
4106         for (j = 0; j <= i; j++) {
4107                 char type;
4108
4109                 r = sd_bus_message_peek_type(m, &type, NULL);
4110                 if (r < 0)
4111                         return NULL;
4112
4113                 if (type != SD_BUS_TYPE_STRING &&
4114                     type != SD_BUS_TYPE_OBJECT_PATH &&
4115                     type != SD_BUS_TYPE_SIGNATURE)
4116                         return NULL;
4117
4118                 r = sd_bus_message_read_basic(m, type, &t);
4119                 if (r < 0)
4120                         return NULL;
4121         }
4122
4123         return t;
4124 }
4125
4126 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4127         size_t full;
4128
4129         assert(h);
4130         assert(size);
4131
4132         if (size < sizeof(struct bus_header))
4133                 return false;
4134
4135         full = sizeof(struct bus_header) +
4136                 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4137
4138         return size >= full;
4139 }
4140
4141 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4142         size_t fs, bs;
4143
4144         assert(h);
4145         assert(sum);
4146
4147         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4148                 fs = h->fields_size;
4149                 bs = h->body_size;
4150         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4151                 fs = bswap_32(h->fields_size);
4152                 bs = bswap_32(h->body_size);
4153         } else
4154                 return -EBADMSG;
4155
4156         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4157         return 0;
4158 }