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