Revert "Drop kdbus bits"
[platform/upstream/systemd.git] / src / libsystemd / sd-bus / bus-message.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2013 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <sys/mman.h>
23
24 #include "sd-bus.h"
25
26 #include "alloc-util.h"
27 #include "bus-gvariant.h"
28 #include "bus-internal.h"
29 #include "bus-message.h"
30 #include "bus-signature.h"
31 #include "bus-type.h"
32 #include "bus-util.h"
33 #include "fd-util.h"
34 #include "io-util.h"
35 #include "memfd-util.h"
36 #include "string-util.h"
37 #include "strv.h"
38 #include "time-util.h"
39 #include "utf8.h"
40 #include "util.h"
41
42 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
43
44 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45
46         if (p == NULL)
47                 return NULL;
48
49         if (old_base == new_base)
50                 return (void*) p;
51
52         if ((uint8_t*) p < (uint8_t*) old_base)
53                 return (void*) p;
54
55         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
56                 return (void*) p;
57
58         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
59 }
60
61 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
62         assert(m);
63         assert(part);
64
65         if (part->memfd >= 0) {
66                 /* If we can reuse the memfd, try that. For that it
67                  * can't be sealed yet. */
68
69                 if (!part->sealed) {
70                         assert(part->memfd_offset == 0);
71                         assert(part->data == part->mmap_begin);
72                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
73                 } else {
74                         if (part->mapped > 0)
75                                 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
76
77                         safe_close(part->memfd);
78                 }
79
80         } else if (part->munmap_this)
81                 munmap(part->mmap_begin, part->mapped);
82         else if (part->free_this)
83                 free(part->data);
84
85         if (part != &m->body)
86                 free(part);
87 }
88
89 static void message_reset_parts(sd_bus_message *m) {
90         struct bus_body_part *part;
91
92         assert(m);
93
94         part = &m->body;
95         while (m->n_body_parts > 0) {
96                 struct bus_body_part *next = part->next;
97                 message_free_part(m, part);
98                 part = next;
99                 m->n_body_parts--;
100         }
101
102         m->body_end = NULL;
103
104         m->cached_rindex_part = NULL;
105         m->cached_rindex_part_begin = 0;
106 }
107
108 static void message_reset_containers(sd_bus_message *m) {
109         unsigned i;
110
111         assert(m);
112
113         for (i = 0; i < m->n_containers; i++) {
114                 free(m->containers[i].signature);
115                 free(m->containers[i].offsets);
116         }
117
118         m->containers = mfree(m->containers);
119
120         m->n_containers = m->containers_allocated = 0;
121         m->root_container.index = 0;
122 }
123
124 static void message_free(sd_bus_message *m) {
125         assert(m);
126
127         if (m->free_header)
128                 free(m->header);
129
130         message_reset_parts(m);
131
132         if (m->release_kdbus)
133                 bus_kernel_cmd_free(m->bus, (uint8_t *) m->kdbus - (uint8_t *) m->bus->kdbus_buffer);
134
135         if (m->free_kdbus)
136                 free(m->kdbus);
137
138         sd_bus_unref(m->bus);
139
140         if (m->free_fds) {
141                 close_many(m->fds, m->n_fds);
142                 free(m->fds);
143         }
144
145         if (m->iovec != m->iovec_fixed)
146                 free(m->iovec);
147
148         m->destination_ptr = mfree(m->destination_ptr);
149         message_reset_containers(m);
150         free(m->root_container.signature);
151         free(m->root_container.offsets);
152
153         free(m->root_container.peeked_signature);
154
155         bus_creds_done(&m->creds);
156         free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
160         void *op, *np;
161         size_t old_size, new_size, start;
162
163         assert(m);
164
165         if (m->poisoned)
166                 return NULL;
167
168         old_size = sizeof(struct bus_header) + m->fields_size;
169         start = ALIGN_TO(old_size, align);
170         new_size = start + sz;
171
172         if (new_size < start ||
173             new_size > (size_t) ((uint32_t) -1))
174                 goto poison;
175
176         if (old_size == new_size)
177                 return (uint8_t*) m->header + old_size;
178
179         if (m->free_header) {
180                 np = realloc(m->header, ALIGN8(new_size));
181                 if (!np)
182                         goto poison;
183         } else {
184                 /* Initially, the header is allocated as part of
185                  * the sd_bus_message itself, let's replace it by
186                  * dynamic data */
187
188                 np = malloc(ALIGN8(new_size));
189                 if (!np)
190                         goto poison;
191
192                 memcpy(np, m->header, sizeof(struct bus_header));
193         }
194
195         /* Zero out padding */
196         if (start > old_size)
197                 memzero((uint8_t*) np + old_size, start - old_size);
198
199         op = m->header;
200         m->header = np;
201         m->fields_size = new_size - sizeof(struct bus_header);
202
203         /* Adjust quick access pointers */
204         m->path = adjust_pointer(m->path, op, old_size, m->header);
205         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
206         m->member = adjust_pointer(m->member, op, old_size, m->header);
207         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
208         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
209         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210
211         m->free_header = true;
212
213         if (add_offset) {
214                 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
215                         goto poison;
216
217                 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
218         }
219
220         return (uint8_t*) np + start;
221
222 poison:
223         m->poisoned = true;
224         return NULL;
225 }
226
227 static int message_append_field_string(
228                 sd_bus_message *m,
229                 uint64_t h,
230                 char type,
231                 const char *s,
232                 const char **ret) {
233
234         size_t l;
235         uint8_t *p;
236
237         assert(m);
238
239         /* dbus1 only allows 8bit header field ids */
240         if (h > 0xFF)
241                 return -EINVAL;
242
243         /* dbus1 doesn't allow strings over 32bit, let's enforce this
244          * globally, to not risk convertability */
245         l = strlen(s);
246         if (l > (size_t) (uint32_t) -1)
247                 return -EINVAL;
248
249         /* Signature "(yv)" where the variant contains "s" */
250
251         if (BUS_MESSAGE_IS_GVARIANT(m)) {
252
253                 /* (field id 64bit, ((string + NUL) + NUL + signature string 's') */
254                 p = message_extend_fields(m, 8, 8 + l + 1 + 1 + 1, true);
255                 if (!p)
256                         return -ENOMEM;
257
258                 *((uint64_t*) p) = h;
259                 memcpy(p+8, s, l);
260                 p[8+l] = 0;
261                 p[8+l+1] = 0;
262                 p[8+l+2] = type;
263
264                 if (ret)
265                         *ret = (char*) p + 8;
266
267         } else {
268                 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
269                 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
270                 if (!p)
271                         return -ENOMEM;
272
273                 p[0] = (uint8_t) h;
274                 p[1] = 1;
275                 p[2] = type;
276                 p[3] = 0;
277
278                 ((uint32_t*) p)[1] = l;
279                 memcpy(p + 8, s, l + 1);
280
281                 if (ret)
282                         *ret = (char*) p + 8;
283         }
284
285         return 0;
286 }
287
288 static int message_append_field_signature(
289                 sd_bus_message *m,
290                 uint64_t h,
291                 const char *s,
292                 const char **ret) {
293
294         size_t l;
295         uint8_t *p;
296
297         assert(m);
298
299         /* dbus1 only allows 8bit header field ids */
300         if (h > 0xFF)
301                 return -EINVAL;
302
303         /* dbus1 doesn't allow signatures over 8bit, let's enforce
304          * this globally, to not risk convertability */
305         l = strlen(s);
306         if (l > 255)
307                 return -EINVAL;
308
309         /* Signature "(yv)" where the variant contains "g" */
310
311         if (BUS_MESSAGE_IS_GVARIANT(m))
312                 /* For gvariant the serialization is the same as for normal strings */
313                 return message_append_field_string(m, h, 'g', s, ret);
314         else {
315                 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
316                 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
317                 if (!p)
318                         return -ENOMEM;
319
320                 p[0] = (uint8_t) h;
321                 p[1] = 1;
322                 p[2] = SD_BUS_TYPE_SIGNATURE;
323                 p[3] = 0;
324                 p[4] = l;
325                 memcpy(p + 5, s, l + 1);
326
327                 if (ret)
328                         *ret = (const char*) p + 5;
329         }
330
331         return 0;
332 }
333
334 static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x) {
335         uint8_t *p;
336
337         assert(m);
338
339         /* dbus1 only allows 8bit header field ids */
340         if (h > 0xFF)
341                 return -EINVAL;
342
343         if (BUS_MESSAGE_IS_GVARIANT(m)) {
344                 /* (field id 64bit + ((value + NUL + signature string 'u') */
345
346                 p = message_extend_fields(m, 8, 8 + 4 + 1 + 1, true);
347                 if (!p)
348                         return -ENOMEM;
349
350                 *((uint64_t*) p) = h;
351                 *((uint32_t*) (p + 8)) = x;
352                 p[12] = 0;
353                 p[13] = 'u';
354         } else {
355                 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
356                 p = message_extend_fields(m, 8, 4 + 4, false);
357                 if (!p)
358                         return -ENOMEM;
359
360                 p[0] = (uint8_t) h;
361                 p[1] = 1;
362                 p[2] = 'u';
363                 p[3] = 0;
364
365                 ((uint32_t*) p)[1] = x;
366         }
367
368         return 0;
369 }
370
371 static int message_append_field_uint64(sd_bus_message *m, uint64_t h, uint64_t x) {
372         uint8_t *p;
373
374         assert(m);
375
376         /* dbus1 only allows 8bit header field ids */
377         if (h > 0xFF)
378                 return -EINVAL;
379
380         if (BUS_MESSAGE_IS_GVARIANT(m)) {
381                 /* (field id 64bit + ((value + NUL + signature string 't') */
382
383                 p = message_extend_fields(m, 8, 8 + 8 + 1 + 1, true);
384                 if (!p)
385                         return -ENOMEM;
386
387                 *((uint64_t*) p) = h;
388                 *((uint64_t*) (p + 8)) = x;
389                 p[16] = 0;
390                 p[17] = 't';
391         } else {
392                 /* (field id byte + (signature length + signature 't' + NUL) + 4 byte padding + value) */
393                 p = message_extend_fields(m, 8, 4 + 4 + 8, false);
394                 if (!p)
395                         return -ENOMEM;
396
397                 p[0] = (uint8_t) h;
398                 p[1] = 1;
399                 p[2] = 't';
400                 p[3] = 0;
401                 p[4] = 0;
402                 p[5] = 0;
403                 p[6] = 0;
404                 p[7] = 0;
405
406                 ((uint64_t*) p)[1] = x;
407         }
408
409         return 0;
410 }
411
412 static int message_append_reply_cookie(sd_bus_message *m, uint64_t cookie) {
413         assert(m);
414
415         if (BUS_MESSAGE_IS_GVARIANT(m))
416                 return message_append_field_uint64(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, cookie);
417         else {
418                 /* 64bit cookies are not supported on dbus1 */
419                 if (cookie > 0xffffffffUL)
420                         return -EOPNOTSUPP;
421
422                 return message_append_field_uint32(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) cookie);
423         }
424 }
425
426 int bus_message_from_header(
427                 sd_bus *bus,
428                 void *header,
429                 size_t header_accessible,
430                 void *footer,
431                 size_t footer_accessible,
432                 size_t message_size,
433                 int *fds,
434                 unsigned n_fds,
435                 const char *label,
436                 size_t extra,
437                 sd_bus_message **ret) {
438
439         _cleanup_free_ sd_bus_message *m = NULL;
440         struct bus_header *h;
441         size_t a, label_sz;
442
443         assert(bus);
444         assert(header || header_accessible <= 0);
445         assert(footer || footer_accessible <= 0);
446         assert(fds || n_fds <= 0);
447         assert(ret);
448
449         if (header_accessible < sizeof(struct bus_header))
450                 return -EBADMSG;
451
452         if (header_accessible > message_size)
453                 return -EBADMSG;
454         if (footer_accessible > message_size)
455                 return -EBADMSG;
456
457         h = header;
458         if (!IN_SET(h->version, 1, 2))
459                 return -EBADMSG;
460
461         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
462                 return -EBADMSG;
463
464         if (!IN_SET(h->endian, BUS_LITTLE_ENDIAN, BUS_BIG_ENDIAN))
465                 return -EBADMSG;
466
467         /* Note that we are happy with unknown flags in the flags header! */
468
469         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
470
471         if (label) {
472                 label_sz = strlen(label);
473                 a += label_sz + 1;
474         }
475
476         m = malloc0(a);
477         if (!m)
478                 return -ENOMEM;
479
480         m->n_ref = 1;
481         m->sealed = true;
482         m->header = header;
483         m->header_accessible = header_accessible;
484         m->footer = footer;
485         m->footer_accessible = footer_accessible;
486
487         if (BUS_MESSAGE_IS_GVARIANT(m)) {
488                 size_t ws;
489
490                 if (h->dbus2.cookie == 0)
491                         return -EBADMSG;
492
493                 /* dbus2 derives the sizes from the message size and
494                 the offset table at the end, since it is formatted as
495                 gvariant "yyyyuta{tv}v". Since the message itself is a
496                 structure with precisely to variable sized entries,
497                 there's only one offset in the table, which marks the
498                 end of the fields array. */
499
500                 ws = bus_gvariant_determine_word_size(message_size, 0);
501                 if (footer_accessible < ws)
502                         return -EBADMSG;
503
504                 m->fields_size = bus_gvariant_read_word_le((uint8_t*) footer + footer_accessible - ws, ws);
505                 if (ALIGN8(m->fields_size) > message_size - ws)
506                         return -EBADMSG;
507                 if (m->fields_size < sizeof(struct bus_header))
508                         return -EBADMSG;
509
510                 m->fields_size -= sizeof(struct bus_header);
511                 m->body_size = message_size - (sizeof(struct bus_header) + ALIGN8(m->fields_size));
512         } else {
513                 if (h->dbus1.serial == 0)
514                         return -EBADMSG;
515
516                 /* dbus1 has the sizes in the header */
517                 m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
518                 m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
519
520                 if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
521                         return -EBADMSG;
522         }
523
524         m->fds = fds;
525         m->n_fds = n_fds;
526
527         if (label) {
528                 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
529                 memcpy(m->creds.label, label, label_sz + 1);
530
531                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
532         }
533
534         m->bus = sd_bus_ref(bus);
535         *ret = m;
536         m = NULL;
537
538         return 0;
539 }
540
541 int bus_message_from_malloc(
542                 sd_bus *bus,
543                 void *buffer,
544                 size_t length,
545                 int *fds,
546                 unsigned n_fds,
547                 const char *label,
548                 sd_bus_message **ret) {
549
550         sd_bus_message *m;
551         size_t sz;
552         int r;
553
554         r = bus_message_from_header(
555                         bus,
556                         buffer, length, /* in this case the initial bytes and the final bytes are the same */
557                         buffer, length,
558                         length,
559                         fds, n_fds,
560                         label,
561                         0, &m);
562         if (r < 0)
563                 return r;
564
565         sz = length - sizeof(struct bus_header) - ALIGN8(m->fields_size);
566         if (sz > 0) {
567                 m->n_body_parts = 1;
568                 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(m->fields_size);
569                 m->body.size = sz;
570                 m->body.sealed = true;
571                 m->body.memfd = -1;
572         }
573
574         m->n_iovec = 1;
575         m->iovec = m->iovec_fixed;
576         m->iovec[0].iov_base = buffer;
577         m->iovec[0].iov_len = length;
578
579         r = bus_message_parse_fields(m);
580         if (r < 0)
581                 goto fail;
582
583         /* We take possession of the memory and fds now */
584         m->free_header = true;
585         m->free_fds = true;
586
587         *ret = m;
588         return 0;
589
590 fail:
591         message_free(m);
592         return r;
593 }
594
595 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
596         sd_bus_message *m;
597
598         assert(bus);
599
600         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
601         if (!m)
602                 return NULL;
603
604         m->n_ref = 1;
605         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
606         m->header->endian = BUS_NATIVE_ENDIAN;
607         m->header->type = type;
608         m->header->version = bus->message_version;
609         m->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING);
610         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
611         m->bus = sd_bus_ref(bus);
612
613         if (bus->allow_interactive_authorization)
614                 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
615
616         return m;
617 }
618
619 _public_ int sd_bus_message_new_signal(
620                 sd_bus *bus,
621                 sd_bus_message **m,
622                 const char *path,
623                 const char *interface,
624                 const char *member) {
625
626         sd_bus_message *t;
627         int r;
628
629         assert_return(bus, -ENOTCONN);
630         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
631         assert_return(object_path_is_valid(path), -EINVAL);
632         assert_return(interface_name_is_valid(interface), -EINVAL);
633         assert_return(member_name_is_valid(member), -EINVAL);
634         assert_return(m, -EINVAL);
635
636         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
637         if (!t)
638                 return -ENOMEM;
639
640         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
641
642         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
643         if (r < 0)
644                 goto fail;
645         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
646         if (r < 0)
647                 goto fail;
648         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
649         if (r < 0)
650                 goto fail;
651
652         *m = t;
653         return 0;
654
655 fail:
656         sd_bus_message_unref(t);
657         return r;
658 }
659
660 _public_ int sd_bus_message_new_method_call(
661                 sd_bus *bus,
662                 sd_bus_message **m,
663                 const char *destination,
664                 const char *path,
665                 const char *interface,
666                 const char *member) {
667
668         sd_bus_message *t;
669         int r;
670
671         assert_return(bus, -ENOTCONN);
672         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
673         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
674         assert_return(object_path_is_valid(path), -EINVAL);
675         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
676         assert_return(member_name_is_valid(member), -EINVAL);
677         assert_return(m, -EINVAL);
678
679         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
680         if (!t)
681                 return -ENOMEM;
682
683         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
684         if (r < 0)
685                 goto fail;
686         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
687         if (r < 0)
688                 goto fail;
689
690         if (interface) {
691                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
692                 if (r < 0)
693                         goto fail;
694         }
695
696         if (destination) {
697                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
698                 if (r < 0)
699                         goto fail;
700         }
701
702         *m = t;
703         return 0;
704
705 fail:
706         message_free(t);
707         return r;
708 }
709
710 static int message_new_reply(
711                 sd_bus_message *call,
712                 uint8_t type,
713                 sd_bus_message **m) {
714
715         sd_bus_message *t;
716         int r;
717
718         assert_return(call, -EINVAL);
719         assert_return(call->sealed, -EPERM);
720         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
721         assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
722         assert_return(m, -EINVAL);
723
724         t = message_new(call->bus, type);
725         if (!t)
726                 return -ENOMEM;
727
728         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
729         t->reply_cookie = BUS_MESSAGE_COOKIE(call);
730         if (t->reply_cookie == 0)
731                 return -EOPNOTSUPP;
732
733         r = message_append_reply_cookie(t, t->reply_cookie);
734         if (r < 0)
735                 goto fail;
736
737         if (call->sender) {
738                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
739                 if (r < 0)
740                         goto fail;
741         }
742
743         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
744         t->enforced_reply_signature = call->enforced_reply_signature;
745
746         *m = t;
747         return 0;
748
749 fail:
750         message_free(t);
751         return r;
752 }
753
754 _public_ int sd_bus_message_new_method_return(
755                 sd_bus_message *call,
756                 sd_bus_message **m) {
757
758         return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
759 }
760
761 _public_ int sd_bus_message_new_method_error(
762                 sd_bus_message *call,
763                 sd_bus_message **m,
764                 const sd_bus_error *e) {
765
766         sd_bus_message *t;
767         int r;
768
769         assert_return(sd_bus_error_is_set(e), -EINVAL);
770         assert_return(m, -EINVAL);
771
772         r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
773         if (r < 0)
774                 return r;
775
776         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
777         if (r < 0)
778                 goto fail;
779
780         if (e->message) {
781                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
782                 if (r < 0)
783                         goto fail;
784         }
785
786         t->error._need_free = -1;
787
788         *m = t;
789         return 0;
790
791 fail:
792         message_free(t);
793         return r;
794 }
795
796 _public_ int sd_bus_message_new_method_errorf(
797                 sd_bus_message *call,
798                 sd_bus_message **m,
799                 const char *name,
800                 const char *format,
801                 ...) {
802
803         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
804         va_list ap;
805
806         assert_return(name, -EINVAL);
807         assert_return(m, -EINVAL);
808
809         va_start(ap, format);
810         bus_error_setfv(&error, name, format, ap);
811         va_end(ap);
812
813         return sd_bus_message_new_method_error(call, m, &error);
814 }
815
816 _public_ int sd_bus_message_new_method_errno(
817                 sd_bus_message *call,
818                 sd_bus_message **m,
819                 int error,
820                 const sd_bus_error *p) {
821
822         _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
823
824         if (sd_bus_error_is_set(p))
825                 return sd_bus_message_new_method_error(call, m, p);
826
827         sd_bus_error_set_errno(&berror, error);
828
829         return sd_bus_message_new_method_error(call, m, &berror);
830 }
831
832 _public_ int sd_bus_message_new_method_errnof(
833                 sd_bus_message *call,
834                 sd_bus_message **m,
835                 int error,
836                 const char *format,
837                 ...) {
838
839         _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
840         va_list ap;
841
842         va_start(ap, format);
843         sd_bus_error_set_errnofv(&berror, error, format, ap);
844         va_end(ap);
845
846         return sd_bus_message_new_method_error(call, m, &berror);
847 }
848
849 void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
850         assert(bus);
851         assert(m);
852
853         m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local";
854         m->creds.well_known_names_local = true;
855         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
856 }
857
858 void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m) {
859         assert(bus);
860         assert(m);
861
862         m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
863         m->creds.well_known_names_driver = true;
864         m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
865 }
866
867 int bus_message_new_synthetic_error(
868                 sd_bus *bus,
869                 uint64_t cookie,
870                 const sd_bus_error *e,
871                 sd_bus_message **m) {
872
873         sd_bus_message *t;
874         int r;
875
876         assert(bus);
877         assert(sd_bus_error_is_set(e));
878         assert(m);
879
880         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
881         if (!t)
882                 return -ENOMEM;
883
884         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
885         t->reply_cookie = cookie;
886
887         r = message_append_reply_cookie(t, t->reply_cookie);
888         if (r < 0)
889                 goto fail;
890
891         if (bus && bus->unique_name) {
892                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
893                 if (r < 0)
894                         goto fail;
895         }
896
897         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
898         if (r < 0)
899                 goto fail;
900
901         if (e->message) {
902                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
903                 if (r < 0)
904                         goto fail;
905         }
906
907         t->error._need_free = -1;
908
909         bus_message_set_sender_driver(bus, t);
910
911         *m = t;
912         return 0;
913
914 fail:
915         message_free(t);
916         return r;
917 }
918
919 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
920
921         if (!m)
922                 return NULL;
923
924         assert(m->n_ref > 0);
925         m->n_ref++;
926
927         return m;
928 }
929
930 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
931
932         if (!m)
933                 return NULL;
934
935         assert(m->n_ref > 0);
936         m->n_ref--;
937
938         if (m->n_ref > 0)
939                 return NULL;
940
941         message_free(m);
942         return NULL;
943 }
944
945 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
946         assert_return(m, -EINVAL);
947         assert_return(type, -EINVAL);
948
949         *type = m->header->type;
950         return 0;
951 }
952
953 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
954         uint64_t c;
955
956         assert_return(m, -EINVAL);
957         assert_return(cookie, -EINVAL);
958
959         c = BUS_MESSAGE_COOKIE(m);
960         if (c == 0)
961                 return -ENODATA;
962
963         *cookie = BUS_MESSAGE_COOKIE(m);
964         return 0;
965 }
966
967 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
968         assert_return(m, -EINVAL);
969         assert_return(cookie, -EINVAL);
970
971         if (m->reply_cookie == 0)
972                 return -ENODATA;
973
974         *cookie = m->reply_cookie;
975         return 0;
976 }
977
978 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
979         assert_return(m, -EINVAL);
980
981         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
982                 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
983 }
984
985 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
986         assert_return(m, -EINVAL);
987
988         return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
989 }
990
991 _public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
992         assert_return(m, -EINVAL);
993
994         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
995                 (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
996 }
997
998 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
999         assert_return(m, NULL);
1000
1001         return m->path;
1002 }
1003
1004 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
1005         assert_return(m, NULL);
1006
1007         return m->interface;
1008 }
1009
1010 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
1011         assert_return(m, NULL);
1012
1013         return m->member;
1014 }
1015
1016 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
1017         assert_return(m, NULL);
1018
1019         return m->destination;
1020 }
1021
1022 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
1023         assert_return(m, NULL);
1024
1025         return m->sender;
1026 }
1027
1028 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
1029         assert_return(m, NULL);
1030
1031         if (!sd_bus_error_is_set(&m->error))
1032                 return NULL;
1033
1034         return &m->error;
1035 }
1036
1037 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
1038         assert_return(m, -EINVAL);
1039         assert_return(usec, -EINVAL);
1040
1041         if (m->monotonic <= 0)
1042                 return -ENODATA;
1043
1044         *usec = m->monotonic;
1045         return 0;
1046 }
1047
1048 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
1049         assert_return(m, -EINVAL);
1050         assert_return(usec, -EINVAL);
1051
1052         if (m->realtime <= 0)
1053                 return -ENODATA;
1054
1055         *usec = m->realtime;
1056         return 0;
1057 }
1058
1059 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
1060         assert_return(m, -EINVAL);
1061         assert_return(seqnum, -EINVAL);
1062
1063         if (m->seqnum <= 0)
1064                 return -ENODATA;
1065
1066         *seqnum = m->seqnum;
1067         return 0;
1068 }
1069
1070 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
1071         assert_return(m, NULL);
1072
1073         if (m->creds.mask == 0)
1074                 return NULL;
1075
1076         return &m->creds;
1077 }
1078
1079 _public_ int sd_bus_message_is_signal(
1080                 sd_bus_message *m,
1081                 const char *interface,
1082                 const char *member) {
1083
1084         assert_return(m, -EINVAL);
1085
1086         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1087                 return 0;
1088
1089         if (interface && (!m->interface || !streq(m->interface, interface)))
1090                 return 0;
1091
1092         if (member &&  (!m->member || !streq(m->member, member)))
1093                 return 0;
1094
1095         return 1;
1096 }
1097
1098 _public_ int sd_bus_message_is_method_call(
1099                 sd_bus_message *m,
1100                 const char *interface,
1101                 const char *member) {
1102
1103         assert_return(m, -EINVAL);
1104
1105         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1106                 return 0;
1107
1108         if (interface && (!m->interface || !streq(m->interface, interface)))
1109                 return 0;
1110
1111         if (member &&  (!m->member || !streq(m->member, member)))
1112                 return 0;
1113
1114         return 1;
1115 }
1116
1117 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1118         assert_return(m, -EINVAL);
1119
1120         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1121                 return 0;
1122
1123         if (name && (!m->error.name || !streq(m->error.name, name)))
1124                 return 0;
1125
1126         return 1;
1127 }
1128
1129 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
1130         assert_return(m, -EINVAL);
1131         assert_return(!m->sealed, -EPERM);
1132         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1133
1134         SET_FLAG(m->header->flags, BUS_MESSAGE_NO_REPLY_EXPECTED, !b);
1135
1136         return 0;
1137 }
1138
1139 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
1140         assert_return(m, -EINVAL);
1141         assert_return(!m->sealed, -EPERM);
1142
1143         SET_FLAG(m->header->flags, BUS_MESSAGE_NO_AUTO_START, !b);
1144
1145         return 0;
1146 }
1147
1148 _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
1149         assert_return(m, -EINVAL);
1150         assert_return(!m->sealed, -EPERM);
1151
1152         SET_FLAG(m->header->flags, BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION, b);
1153
1154         return 0;
1155 }
1156
1157 static struct bus_container *message_get_container(sd_bus_message *m) {
1158         assert(m);
1159
1160         if (m->n_containers == 0)
1161                 return &m->root_container;
1162
1163         assert(m->containers);
1164         return m->containers + m->n_containers - 1;
1165 }
1166
1167 struct bus_body_part *message_append_part(sd_bus_message *m) {
1168         struct bus_body_part *part;
1169
1170         assert(m);
1171
1172         if (m->poisoned)
1173                 return NULL;
1174
1175         if (m->n_body_parts <= 0) {
1176                 part = &m->body;
1177                 zero(*part);
1178         } else {
1179                 assert(m->body_end);
1180
1181                 part = new0(struct bus_body_part, 1);
1182                 if (!part) {
1183                         m->poisoned = true;
1184                         return NULL;
1185                 }
1186
1187                 m->body_end->next = part;
1188         }
1189
1190         part->memfd = -1;
1191         m->body_end = part;
1192         m->n_body_parts++;
1193
1194         return part;
1195 }
1196
1197 static void part_zero(struct bus_body_part *part, size_t sz) {
1198         assert(part);
1199         assert(sz > 0);
1200         assert(sz < 8);
1201
1202         /* All other fields can be left in their defaults */
1203         assert(!part->data);
1204         assert(part->memfd < 0);
1205
1206         part->size = sz;
1207         part->is_zero = true;
1208         part->sealed = true;
1209 }
1210
1211 static int part_make_space(
1212                 struct sd_bus_message *m,
1213                 struct bus_body_part *part,
1214                 size_t sz,
1215                 void **q) {
1216
1217         void *n;
1218         int r;
1219
1220         assert(m);
1221         assert(part);
1222         assert(!part->sealed);
1223
1224         if (m->poisoned)
1225                 return -ENOMEM;
1226
1227         if (!part->data && part->memfd < 0) {
1228                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1229                 part->mmap_begin = part->data;
1230         }
1231
1232         if (part->memfd >= 0) {
1233
1234                 if (part->allocated == 0 || sz > part->allocated) {
1235                         uint64_t new_allocated;
1236
1237                         new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1238                         r = memfd_set_size(part->memfd, new_allocated);
1239                         if (r < 0) {
1240                                 m->poisoned = true;
1241                                 return r;
1242                         }
1243
1244                         part->allocated = new_allocated;
1245                 }
1246
1247                 if (!part->data || sz > part->mapped) {
1248                         size_t psz;
1249
1250                         psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1251                         if (part->mapped <= 0)
1252                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1253                         else
1254                                 n = mremap(part->mmap_begin, part->mapped, psz, MREMAP_MAYMOVE);
1255
1256                         if (n == MAP_FAILED) {
1257                                 m->poisoned = true;
1258                                 return -errno;
1259                         }
1260
1261                         part->mmap_begin = part->data = n;
1262                         part->mapped = psz;
1263                         part->memfd_offset = 0;
1264                 }
1265
1266                 part->munmap_this = true;
1267         } else {
1268                 if (part->allocated == 0 || sz > part->allocated) {
1269                         size_t new_allocated;
1270
1271                         new_allocated = sz > 0 ? 2 * sz : 64;
1272                         n = realloc(part->data, new_allocated);
1273                         if (!n) {
1274                                 m->poisoned = true;
1275                                 return -ENOMEM;
1276                         }
1277
1278                         part->data = n;
1279                         part->allocated = new_allocated;
1280                         part->free_this = true;
1281                 }
1282         }
1283
1284         if (q)
1285                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1286
1287         part->size = sz;
1288         return 0;
1289 }
1290
1291 static int message_add_offset(sd_bus_message *m, size_t offset) {
1292         struct bus_container *c;
1293
1294         assert(m);
1295         assert(BUS_MESSAGE_IS_GVARIANT(m));
1296
1297         /* Add offset to current container, unless this is the first
1298          * item in it, which will have the 0 offset, which we can
1299          * ignore. */
1300         c = message_get_container(m);
1301
1302         if (!c->need_offsets)
1303                 return 0;
1304
1305         if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1306                 return -ENOMEM;
1307
1308         c->offsets[c->n_offsets++] = offset;
1309         return 0;
1310 }
1311
1312 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1313         struct bus_container *c;
1314
1315         assert(m);
1316
1317         if (expand <= 0)
1318                 return;
1319
1320         /* Update counters */
1321         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1322
1323                 if (c->array_size)
1324                         *c->array_size += expand;
1325         }
1326 }
1327
1328 static void *message_extend_body(
1329                 sd_bus_message *m,
1330                 size_t align,
1331                 size_t sz,
1332                 bool add_offset,
1333                 bool force_inline) {
1334
1335         size_t start_body, end_body, padding, added;
1336         void *p;
1337         int r;
1338
1339         assert(m);
1340         assert(align > 0);
1341         assert(!m->sealed);
1342
1343         if (m->poisoned)
1344                 return NULL;
1345
1346         start_body = ALIGN_TO((size_t) m->body_size, align);
1347         end_body = start_body + sz;
1348
1349         padding = start_body - m->body_size;
1350         added = padding + sz;
1351
1352         /* Check for 32bit overflows */
1353         if (end_body > (size_t) ((uint32_t) -1) ||
1354             end_body < start_body) {
1355                 m->poisoned = true;
1356                 return NULL;
1357         }
1358
1359         if (added > 0) {
1360                 struct bus_body_part *part = NULL;
1361                 bool add_new_part;
1362
1363                 add_new_part =
1364                         m->n_body_parts <= 0 ||
1365                         m->body_end->sealed ||
1366                         (padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) ||
1367                         (force_inline && m->body_end->size > MEMFD_MIN_SIZE); /* if this must be an inlined extension, let's create a new part if the previous part is large enough to be inlined */
1368
1369                 if (add_new_part) {
1370                         if (padding > 0) {
1371                                 part = message_append_part(m);
1372                                 if (!part)
1373                                         return NULL;
1374
1375                                 part_zero(part, padding);
1376                         }
1377
1378                         part = message_append_part(m);
1379                         if (!part)
1380                                 return NULL;
1381
1382                         r = part_make_space(m, part, sz, &p);
1383                         if (r < 0)
1384                                 return NULL;
1385                 } else {
1386                         struct bus_container *c;
1387                         void *op;
1388                         size_t os, start_part, end_part;
1389
1390                         part = m->body_end;
1391                         op = part->data;
1392                         os = part->size;
1393
1394                         start_part = ALIGN_TO(part->size, align);
1395                         end_part = start_part + sz;
1396
1397                         r = part_make_space(m, part, end_part, &p);
1398                         if (r < 0)
1399                                 return NULL;
1400
1401                         if (padding > 0) {
1402                                 memzero(p, padding);
1403                                 p = (uint8_t*) p + padding;
1404                         }
1405
1406                         /* Readjust pointers */
1407                         for (c = m->containers; c < m->containers + m->n_containers; c++)
1408                                 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1409
1410                         m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1411                 }
1412         } else
1413                 /* Return something that is not NULL and is aligned */
1414                 p = (uint8_t *) NULL + align;
1415
1416         m->body_size = end_body;
1417         message_extend_containers(m, added);
1418
1419         if (add_offset) {
1420                 r = message_add_offset(m, end_body);
1421                 if (r < 0) {
1422                         m->poisoned = true;
1423                         return NULL;
1424                 }
1425         }
1426
1427         return p;
1428 }
1429
1430 static int message_push_fd(sd_bus_message *m, int fd) {
1431         int *f, copy;
1432
1433         assert(m);
1434
1435         if (fd < 0)
1436                 return -EINVAL;
1437
1438         if (!m->allow_fds)
1439                 return -EOPNOTSUPP;
1440
1441         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1442         if (copy < 0)
1443                 return -errno;
1444
1445         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1446         if (!f) {
1447                 m->poisoned = true;
1448                 safe_close(copy);
1449                 return -ENOMEM;
1450         }
1451
1452         m->fds = f;
1453         m->fds[m->n_fds] = copy;
1454         m->free_fds = true;
1455
1456         return copy;
1457 }
1458
1459 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1460         _cleanup_close_ int fd = -1;
1461         struct bus_container *c;
1462         ssize_t align, sz;
1463         void *a;
1464
1465         assert_return(m, -EINVAL);
1466         assert_return(!m->sealed, -EPERM);
1467         assert_return(bus_type_is_basic(type), -EINVAL);
1468         assert_return(!m->poisoned, -ESTALE);
1469
1470         c = message_get_container(m);
1471
1472         if (c->signature && c->signature[c->index]) {
1473                 /* Container signature is already set */
1474
1475                 if (c->signature[c->index] != type)
1476                         return -ENXIO;
1477         } else {
1478                 char *e;
1479
1480                 /* Maybe we can append to the signature? But only if this is the top-level container */
1481                 if (c->enclosing != 0)
1482                         return -ENXIO;
1483
1484                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1485                 if (!e) {
1486                         m->poisoned = true;
1487                         return -ENOMEM;
1488                 }
1489         }
1490
1491         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1492                 uint8_t u8;
1493                 uint32_t u32;
1494
1495                 switch (type) {
1496
1497                 case SD_BUS_TYPE_SIGNATURE:
1498                 case SD_BUS_TYPE_STRING:
1499                         p = strempty(p);
1500
1501                         /* Fall through... */
1502                 case SD_BUS_TYPE_OBJECT_PATH:
1503                         if (!p)
1504                                 return -EINVAL;
1505
1506                         align = 1;
1507                         sz = strlen(p) + 1;
1508                         break;
1509
1510                 case SD_BUS_TYPE_BOOLEAN:
1511
1512                         u8 = p && *(int*) p;
1513                         p = &u8;
1514
1515                         align = sz = 1;
1516                         break;
1517
1518                 case SD_BUS_TYPE_UNIX_FD:
1519
1520                         if (!p)
1521                                 return -EINVAL;
1522
1523                         fd = message_push_fd(m, *(int*) p);
1524                         if (fd < 0)
1525                                 return fd;
1526
1527                         u32 = m->n_fds;
1528                         p = &u32;
1529
1530                         align = sz = 4;
1531                         break;
1532
1533                 default:
1534                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1535                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1536                         break;
1537                 }
1538
1539                 assert(align > 0);
1540                 assert(sz > 0);
1541
1542                 a = message_extend_body(m, align, sz, true, false);
1543                 if (!a)
1544                         return -ENOMEM;
1545
1546                 memcpy(a, p, sz);
1547
1548                 if (stored)
1549                         *stored = (const uint8_t*) a;
1550
1551         } else {
1552                 uint32_t u32;
1553
1554                 switch (type) {
1555
1556                 case SD_BUS_TYPE_STRING:
1557                         /* To make things easy we'll serialize a NULL string
1558                          * into the empty string */
1559                         p = strempty(p);
1560
1561                         /* Fall through... */
1562                 case SD_BUS_TYPE_OBJECT_PATH:
1563
1564                         if (!p)
1565                                 return -EINVAL;
1566
1567                         align = 4;
1568                         sz = 4 + strlen(p) + 1;
1569                         break;
1570
1571                 case SD_BUS_TYPE_SIGNATURE:
1572
1573                         p = strempty(p);
1574
1575                         align = 1;
1576                         sz = 1 + strlen(p) + 1;
1577                         break;
1578
1579                 case SD_BUS_TYPE_BOOLEAN:
1580
1581                         u32 = p && *(int*) p;
1582                         p = &u32;
1583
1584                         align = sz = 4;
1585                         break;
1586
1587                 case SD_BUS_TYPE_UNIX_FD:
1588
1589                         if (!p)
1590                                 return -EINVAL;
1591
1592                         fd = message_push_fd(m, *(int*) p);
1593                         if (fd < 0)
1594                                 return fd;
1595
1596                         u32 = m->n_fds;
1597                         p = &u32;
1598
1599                         align = sz = 4;
1600                         break;
1601
1602                 default:
1603                         align = bus_type_get_alignment(type);
1604                         sz = bus_type_get_size(type);
1605                         break;
1606                 }
1607
1608                 assert(align > 0);
1609                 assert(sz > 0);
1610
1611                 a = message_extend_body(m, align, sz, false, false);
1612                 if (!a)
1613                         return -ENOMEM;
1614
1615                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
1616                         *(uint32_t*) a = sz - 5;
1617                         memcpy((uint8_t*) a + 4, p, sz - 4);
1618
1619                         if (stored)
1620                                 *stored = (const uint8_t*) a + 4;
1621
1622                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1623                         *(uint8_t*) a = sz - 2;
1624                         memcpy((uint8_t*) a + 1, p, sz - 1);
1625
1626                         if (stored)
1627                                 *stored = (const uint8_t*) a + 1;
1628                 } else {
1629                         memcpy(a, p, sz);
1630
1631                         if (stored)
1632                                 *stored = a;
1633                 }
1634         }
1635
1636         if (type == SD_BUS_TYPE_UNIX_FD)
1637                 m->n_fds++;
1638
1639         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1640                 c->index++;
1641
1642         fd = -1;
1643         return 0;
1644 }
1645
1646 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1647         return message_append_basic(m, type, p, NULL);
1648 }
1649
1650 _public_ int sd_bus_message_append_string_space(
1651                 sd_bus_message *m,
1652                 size_t size,
1653                 char **s) {
1654
1655         struct bus_container *c;
1656         void *a;
1657
1658         assert_return(m, -EINVAL);
1659         assert_return(s, -EINVAL);
1660         assert_return(!m->sealed, -EPERM);
1661         assert_return(!m->poisoned, -ESTALE);
1662
1663         c = message_get_container(m);
1664
1665         if (c->signature && c->signature[c->index]) {
1666                 /* Container signature is already set */
1667
1668                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1669                         return -ENXIO;
1670         } else {
1671                 char *e;
1672
1673                 /* Maybe we can append to the signature? But only if this is the top-level container */
1674                 if (c->enclosing != 0)
1675                         return -ENXIO;
1676
1677                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1678                 if (!e) {
1679                         m->poisoned = true;
1680                         return -ENOMEM;
1681                 }
1682         }
1683
1684         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1685                 a = message_extend_body(m, 1, size + 1, true, false);
1686                 if (!a)
1687                         return -ENOMEM;
1688
1689                 *s = a;
1690         } else {
1691                 a = message_extend_body(m, 4, 4 + size + 1, false, false);
1692                 if (!a)
1693                         return -ENOMEM;
1694
1695                 *(uint32_t*) a = size;
1696                 *s = (char*) a + 4;
1697         }
1698
1699         (*s)[size] = 0;
1700
1701         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1702                 c->index++;
1703
1704         return 0;
1705 }
1706
1707 _public_ int sd_bus_message_append_string_iovec(
1708                 sd_bus_message *m,
1709                 const struct iovec *iov,
1710                 unsigned n) {
1711
1712         size_t size;
1713         unsigned i;
1714         char *p;
1715         int r;
1716
1717         assert_return(m, -EINVAL);
1718         assert_return(!m->sealed, -EPERM);
1719         assert_return(iov || n == 0, -EINVAL);
1720         assert_return(!m->poisoned, -ESTALE);
1721
1722         size = IOVEC_TOTAL_SIZE(iov, n);
1723
1724         r = sd_bus_message_append_string_space(m, size, &p);
1725         if (r < 0)
1726                 return r;
1727
1728         for (i = 0; i < n; i++) {
1729
1730                 if (iov[i].iov_base)
1731                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1732                 else
1733                         memset(p, ' ', iov[i].iov_len);
1734
1735                 p += iov[i].iov_len;
1736         }
1737
1738         return 0;
1739 }
1740
1741 static int bus_message_open_array(
1742                 sd_bus_message *m,
1743                 struct bus_container *c,
1744                 const char *contents,
1745                 uint32_t **array_size,
1746                 size_t *begin,
1747                 bool *need_offsets) {
1748
1749         unsigned nindex;
1750         int alignment, r;
1751
1752         assert(m);
1753         assert(c);
1754         assert(contents);
1755         assert(array_size);
1756         assert(begin);
1757         assert(need_offsets);
1758
1759         if (!signature_is_single(contents, true))
1760                 return -EINVAL;
1761
1762         if (c->signature && c->signature[c->index]) {
1763
1764                 /* Verify the existing signature */
1765
1766                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1767                         return -ENXIO;
1768
1769                 if (!startswith(c->signature + c->index + 1, contents))
1770                         return -ENXIO;
1771
1772                 nindex = c->index + 1 + strlen(contents);
1773         } else {
1774                 char *e;
1775
1776                 if (c->enclosing != 0)
1777                         return -ENXIO;
1778
1779                 /* Extend the existing signature */
1780
1781                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1782                 if (!e) {
1783                         m->poisoned = true;
1784                         return -ENOMEM;
1785                 }
1786
1787                 nindex = e - c->signature;
1788         }
1789
1790         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1791                 alignment = bus_gvariant_get_alignment(contents);
1792                 if (alignment < 0)
1793                         return alignment;
1794
1795                 /* Add alignment padding and add to offset list */
1796                 if (!message_extend_body(m, alignment, 0, false, false))
1797                         return -ENOMEM;
1798
1799                 r = bus_gvariant_is_fixed_size(contents);
1800                 if (r < 0)
1801                         return r;
1802
1803                 *begin = m->body_size;
1804                 *need_offsets = r == 0;
1805         } else {
1806                 void *a, *op;
1807                 size_t os;
1808                 struct bus_body_part *o;
1809
1810                 alignment = bus_type_get_alignment(contents[0]);
1811                 if (alignment < 0)
1812                         return alignment;
1813
1814                 a = message_extend_body(m, 4, 4, false, false);
1815                 if (!a)
1816                         return -ENOMEM;
1817
1818                 o = m->body_end;
1819                 op = m->body_end->data;
1820                 os = m->body_end->size;
1821
1822                 /* Add alignment between size and first element */
1823                 if (!message_extend_body(m, alignment, 0, false, false))
1824                         return -ENOMEM;
1825
1826                 /* location of array size might have changed so let's readjust a */
1827                 if (o == m->body_end)
1828                         a = adjust_pointer(a, op, os, m->body_end->data);
1829
1830                 *(uint32_t*) a = 0;
1831                 *array_size = a;
1832         }
1833
1834         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1835                 c->index = nindex;
1836
1837         return 0;
1838 }
1839
1840 static int bus_message_open_variant(
1841                 sd_bus_message *m,
1842                 struct bus_container *c,
1843                 const char *contents) {
1844
1845         assert(m);
1846         assert(c);
1847         assert(contents);
1848
1849         if (!signature_is_single(contents, false))
1850                 return -EINVAL;
1851
1852         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1853                 return -EINVAL;
1854
1855         if (c->signature && c->signature[c->index]) {
1856
1857                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1858                         return -ENXIO;
1859
1860         } else {
1861                 char *e;
1862
1863                 if (c->enclosing != 0)
1864                         return -ENXIO;
1865
1866                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1867                 if (!e) {
1868                         m->poisoned = true;
1869                         return -ENOMEM;
1870                 }
1871         }
1872
1873         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1874                 /* Variants are always aligned to 8 */
1875
1876                 if (!message_extend_body(m, 8, 0, false, false))
1877                         return -ENOMEM;
1878
1879         } else {
1880                 size_t l;
1881                 void *a;
1882
1883                 l = strlen(contents);
1884                 a = message_extend_body(m, 1, 1 + l + 1, false, false);
1885                 if (!a)
1886                         return -ENOMEM;
1887
1888                 *(uint8_t*) a = l;
1889                 memcpy((uint8_t*) a + 1, contents, l + 1);
1890         }
1891
1892         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1893                 c->index++;
1894
1895         return 0;
1896 }
1897
1898 static int bus_message_open_struct(
1899                 sd_bus_message *m,
1900                 struct bus_container *c,
1901                 const char *contents,
1902                 size_t *begin,
1903                 bool *need_offsets) {
1904
1905         size_t nindex;
1906         int r;
1907
1908         assert(m);
1909         assert(c);
1910         assert(contents);
1911         assert(begin);
1912         assert(need_offsets);
1913
1914         if (!signature_is_valid(contents, false))
1915                 return -EINVAL;
1916
1917         if (c->signature && c->signature[c->index]) {
1918                 size_t l;
1919
1920                 l = strlen(contents);
1921
1922                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1923                     !startswith(c->signature + c->index + 1, contents) ||
1924                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1925                         return -ENXIO;
1926
1927                 nindex = c->index + 1 + l + 1;
1928         } else {
1929                 char *e;
1930
1931                 if (c->enclosing != 0)
1932                         return -ENXIO;
1933
1934                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1935                 if (!e) {
1936                         m->poisoned = true;
1937                         return -ENOMEM;
1938                 }
1939
1940                 nindex = e - c->signature;
1941         }
1942
1943         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1944                 int alignment;
1945
1946                 alignment = bus_gvariant_get_alignment(contents);
1947                 if (alignment < 0)
1948                         return alignment;
1949
1950                 if (!message_extend_body(m, alignment, 0, false, false))
1951                         return -ENOMEM;
1952
1953                 r = bus_gvariant_is_fixed_size(contents);
1954                 if (r < 0)
1955                         return r;
1956
1957                 *begin = m->body_size;
1958                 *need_offsets = r == 0;
1959         } else {
1960                 /* Align contents to 8 byte boundary */
1961                 if (!message_extend_body(m, 8, 0, false, false))
1962                         return -ENOMEM;
1963         }
1964
1965         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1966                 c->index = nindex;
1967
1968         return 0;
1969 }
1970
1971 static int bus_message_open_dict_entry(
1972                 sd_bus_message *m,
1973                 struct bus_container *c,
1974                 const char *contents,
1975                 size_t *begin,
1976                 bool *need_offsets) {
1977
1978         int r;
1979
1980         assert(m);
1981         assert(c);
1982         assert(contents);
1983         assert(begin);
1984         assert(need_offsets);
1985
1986         if (!signature_is_pair(contents))
1987                 return -EINVAL;
1988
1989         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1990                 return -ENXIO;
1991
1992         if (c->signature && c->signature[c->index]) {
1993                 size_t l;
1994
1995                 l = strlen(contents);
1996
1997                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1998                     !startswith(c->signature + c->index + 1, contents) ||
1999                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2000                         return -ENXIO;
2001         } else
2002                 return -ENXIO;
2003
2004         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2005                 int alignment;
2006
2007                 alignment = bus_gvariant_get_alignment(contents);
2008                 if (alignment < 0)
2009                         return alignment;
2010
2011                 if (!message_extend_body(m, alignment, 0, false, false))
2012                         return -ENOMEM;
2013
2014                 r = bus_gvariant_is_fixed_size(contents);
2015                 if (r < 0)
2016                         return r;
2017
2018                 *begin = m->body_size;
2019                 *need_offsets = r == 0;
2020         } else {
2021                 /* Align contents to 8 byte boundary */
2022                 if (!message_extend_body(m, 8, 0, false, false))
2023                         return -ENOMEM;
2024         }
2025
2026         return 0;
2027 }
2028
2029 _public_ int sd_bus_message_open_container(
2030                 sd_bus_message *m,
2031                 char type,
2032                 const char *contents) {
2033
2034         struct bus_container *c, *w;
2035         uint32_t *array_size = NULL;
2036         char *signature;
2037         size_t before, begin = 0;
2038         bool need_offsets = false;
2039         int r;
2040
2041         assert_return(m, -EINVAL);
2042         assert_return(!m->sealed, -EPERM);
2043         assert_return(contents, -EINVAL);
2044         assert_return(!m->poisoned, -ESTALE);
2045
2046         /* Make sure we have space for one more container */
2047         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
2048                 m->poisoned = true;
2049                 return -ENOMEM;
2050         }
2051
2052         c = message_get_container(m);
2053
2054         signature = strdup(contents);
2055         if (!signature) {
2056                 m->poisoned = true;
2057                 return -ENOMEM;
2058         }
2059
2060         /* Save old index in the parent container, in case we have to
2061          * abort this container */
2062         c->saved_index = c->index;
2063         before = m->body_size;
2064
2065         if (type == SD_BUS_TYPE_ARRAY)
2066                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
2067         else if (type == SD_BUS_TYPE_VARIANT)
2068                 r = bus_message_open_variant(m, c, contents);
2069         else if (type == SD_BUS_TYPE_STRUCT)
2070                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
2071         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2072                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
2073         else
2074                 r = -EINVAL;
2075
2076         if (r < 0) {
2077                 free(signature);
2078                 return r;
2079         }
2080
2081         /* OK, let's fill it in */
2082         w = m->containers + m->n_containers++;
2083         w->enclosing = type;
2084         w->signature = signature;
2085         w->index = 0;
2086         w->array_size = array_size;
2087         w->before = before;
2088         w->begin = begin;
2089         w->n_offsets = w->offsets_allocated = 0;
2090         w->offsets = NULL;
2091         w->need_offsets = need_offsets;
2092
2093         return 0;
2094 }
2095
2096 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2097
2098         assert(m);
2099         assert(c);
2100
2101         if (!BUS_MESSAGE_IS_GVARIANT(m))
2102                 return 0;
2103
2104         if (c->need_offsets) {
2105                 size_t payload, sz, i;
2106                 uint8_t *a;
2107
2108                 /* Variable-width arrays */
2109
2110                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2111                 sz = bus_gvariant_determine_word_size(payload, c->n_offsets);
2112
2113                 a = message_extend_body(m, 1, sz * c->n_offsets, true, false);
2114                 if (!a)
2115                         return -ENOMEM;
2116
2117                 for (i = 0; i < c->n_offsets; i++)
2118                         bus_gvariant_write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2119         } else {
2120                 void *a;
2121
2122                 /* Fixed-width or empty arrays */
2123
2124                 a = message_extend_body(m, 1, 0, true, false); /* let's add offset to parent */
2125                 if (!a)
2126                         return -ENOMEM;
2127         }
2128
2129         return 0;
2130 }
2131
2132 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2133         uint8_t *a;
2134         size_t l;
2135
2136         assert(m);
2137         assert(c);
2138         assert(c->signature);
2139
2140         if (!BUS_MESSAGE_IS_GVARIANT(m))
2141                 return 0;
2142
2143         l = strlen(c->signature);
2144
2145         a = message_extend_body(m, 1, 1 + l, true, false);
2146         if (!a)
2147                 return -ENOMEM;
2148
2149         a[0] = 0;
2150         memcpy(a+1, c->signature, l);
2151
2152         return 0;
2153 }
2154
2155 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2156         bool fixed_size = true;
2157         size_t n_variable = 0;
2158         unsigned i = 0;
2159         const char *p;
2160         uint8_t *a;
2161         int r;
2162
2163         assert(m);
2164         assert(c);
2165
2166         if (!BUS_MESSAGE_IS_GVARIANT(m))
2167                 return 0;
2168
2169         p = strempty(c->signature);
2170         while (*p != 0) {
2171                 size_t n;
2172
2173                 r = signature_element_length(p, &n);
2174                 if (r < 0)
2175                         return r;
2176                 else {
2177                         char t[n+1];
2178
2179                         memcpy(t, p, n);
2180                         t[n] = 0;
2181
2182                         r = bus_gvariant_is_fixed_size(t);
2183                         if (r < 0)
2184                                 return r;
2185                 }
2186
2187                 assert(!c->need_offsets || i <= c->n_offsets);
2188
2189                 /* We need to add an offset for each item that has a
2190                  * variable size and that is not the last one in the
2191                  * list */
2192                 if (r == 0)
2193                         fixed_size = false;
2194                 if (r == 0 && p[n] != 0)
2195                         n_variable++;
2196
2197                 i++;
2198                 p += n;
2199         }
2200
2201         assert(!c->need_offsets || i == c->n_offsets);
2202         assert(c->need_offsets || n_variable == 0);
2203
2204         if (isempty(c->signature)) {
2205                 /* The unary type is encoded as fixed 1 byte padding */
2206                 a = message_extend_body(m, 1, 1, add_offset, false);
2207                 if (!a)
2208                         return -ENOMEM;
2209
2210                 *a = 0;
2211         } else if (n_variable <= 0) {
2212                 int alignment = 1;
2213
2214                 /* Structures with fixed-size members only have to be
2215                  * fixed-size themselves. But gvariant requires all fixed-size
2216                  * elements to be sized a multiple of their alignment. Hence,
2217                  * we must *always* add final padding after the last member so
2218                  * the overall size of the structure is properly aligned. */
2219                 if (fixed_size)
2220                         alignment = bus_gvariant_get_alignment(strempty(c->signature));
2221
2222                 assert(alignment > 0);
2223
2224                 a = message_extend_body(m, alignment, 0, add_offset, false);
2225                 if (!a)
2226                         return -ENOMEM;
2227         } else {
2228                 size_t sz;
2229                 unsigned j;
2230
2231                 assert(c->offsets[c->n_offsets-1] == m->body_size);
2232
2233                 sz = bus_gvariant_determine_word_size(m->body_size - c->begin, n_variable);
2234
2235                 a = message_extend_body(m, 1, sz * n_variable, add_offset, false);
2236                 if (!a)
2237                         return -ENOMEM;
2238
2239                 p = strempty(c->signature);
2240                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2241                         unsigned k;
2242                         size_t n;
2243
2244                         r = signature_element_length(p, &n);
2245                         if (r < 0)
2246                                 return r;
2247                         else {
2248                                 char t[n+1];
2249
2250                                 memcpy(t, p, n);
2251                                 t[n] = 0;
2252
2253                                 p += n;
2254
2255                                 r = bus_gvariant_is_fixed_size(t);
2256                                 if (r < 0)
2257                                         return r;
2258                                 if (r > 0 || p[0] == 0)
2259                                         continue;
2260                         }
2261
2262                         k = n_variable - 1 - j;
2263
2264                         bus_gvariant_write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2265
2266                         j++;
2267                 }
2268         }
2269
2270         return 0;
2271 }
2272
2273 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2274         struct bus_container *c;
2275         int r;
2276
2277         assert_return(m, -EINVAL);
2278         assert_return(!m->sealed, -EPERM);
2279         assert_return(m->n_containers > 0, -EINVAL);
2280         assert_return(!m->poisoned, -ESTALE);
2281
2282         c = message_get_container(m);
2283
2284         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2285                 if (c->signature && c->signature[c->index] != 0)
2286                         return -EINVAL;
2287
2288         m->n_containers--;
2289
2290         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2291                 r = bus_message_close_array(m, c);
2292         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2293                 r = bus_message_close_variant(m, c);
2294         else if (IN_SET(c->enclosing, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY))
2295                 r = bus_message_close_struct(m, c, true);
2296         else
2297                 assert_not_reached("Unknown container type");
2298
2299         free(c->signature);
2300         free(c->offsets);
2301
2302         return r;
2303 }
2304
2305 typedef struct {
2306         const char *types;
2307         unsigned n_struct;
2308         unsigned n_array;
2309 } TypeStack;
2310
2311 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2312         assert(stack);
2313         assert(max > 0);
2314
2315         if (*i >= max)
2316                 return -EINVAL;
2317
2318         stack[*i].types = types;
2319         stack[*i].n_struct = n_struct;
2320         stack[*i].n_array = n_array;
2321         (*i)++;
2322
2323         return 0;
2324 }
2325
2326 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2327         assert(stack);
2328         assert(max > 0);
2329         assert(types);
2330         assert(n_struct);
2331         assert(n_array);
2332
2333         if (*i <= 0)
2334                 return 0;
2335
2336         (*i)--;
2337         *types = stack[*i].types;
2338         *n_struct = stack[*i].n_struct;
2339         *n_array = stack[*i].n_array;
2340
2341         return 1;
2342 }
2343
2344 _public_ int sd_bus_message_appendv(
2345                 sd_bus_message *m,
2346                 const char *types,
2347                 va_list ap) {
2348
2349         unsigned n_array, n_struct;
2350         TypeStack stack[BUS_CONTAINER_DEPTH];
2351         unsigned stack_ptr = 0;
2352         int r;
2353
2354         assert_return(m, -EINVAL);
2355         assert_return(types, -EINVAL);
2356         assert_return(!m->sealed, -EPERM);
2357         assert_return(!m->poisoned, -ESTALE);
2358
2359         n_array = (unsigned) -1;
2360         n_struct = strlen(types);
2361
2362         for (;;) {
2363                 const char *t;
2364
2365                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2366                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2367                         if (r < 0)
2368                                 return r;
2369                         if (r == 0)
2370                                 break;
2371
2372                         r = sd_bus_message_close_container(m);
2373                         if (r < 0)
2374                                 return r;
2375
2376                         continue;
2377                 }
2378
2379                 t = types;
2380                 if (n_array != (unsigned) -1)
2381                         n_array--;
2382                 else {
2383                         types++;
2384                         n_struct--;
2385                 }
2386
2387                 switch (*t) {
2388
2389                 case SD_BUS_TYPE_BYTE: {
2390                         uint8_t x;
2391
2392                         x = (uint8_t) va_arg(ap, int);
2393                         r = sd_bus_message_append_basic(m, *t, &x);
2394                         break;
2395                 }
2396
2397                 case SD_BUS_TYPE_BOOLEAN:
2398                 case SD_BUS_TYPE_INT32:
2399                 case SD_BUS_TYPE_UINT32:
2400                 case SD_BUS_TYPE_UNIX_FD: {
2401                         uint32_t x;
2402
2403                         /* We assume a boolean is the same as int32_t */
2404                         assert_cc(sizeof(int32_t) == sizeof(int));
2405
2406                         x = va_arg(ap, uint32_t);
2407                         r = sd_bus_message_append_basic(m, *t, &x);
2408                         break;
2409                 }
2410
2411                 case SD_BUS_TYPE_INT16:
2412                 case SD_BUS_TYPE_UINT16: {
2413                         uint16_t x;
2414
2415                         x = (uint16_t) va_arg(ap, int);
2416                         r = sd_bus_message_append_basic(m, *t, &x);
2417                         break;
2418                 }
2419
2420                 case SD_BUS_TYPE_INT64:
2421                 case SD_BUS_TYPE_UINT64: {
2422                         uint64_t x;
2423
2424                         x = va_arg(ap, uint64_t);
2425                         r = sd_bus_message_append_basic(m, *t, &x);
2426                         break;
2427                 }
2428
2429                 case SD_BUS_TYPE_DOUBLE: {
2430                         double x;
2431
2432                         x = va_arg(ap, double);
2433                         r = sd_bus_message_append_basic(m, *t, &x);
2434                         break;
2435                 }
2436
2437                 case SD_BUS_TYPE_STRING:
2438                 case SD_BUS_TYPE_OBJECT_PATH:
2439                 case SD_BUS_TYPE_SIGNATURE: {
2440                         const char *x;
2441
2442                         x = va_arg(ap, const char*);
2443                         r = sd_bus_message_append_basic(m, *t, x);
2444                         break;
2445                 }
2446
2447                 case SD_BUS_TYPE_ARRAY: {
2448                         size_t k;
2449
2450                         r = signature_element_length(t + 1, &k);
2451                         if (r < 0)
2452                                 return r;
2453
2454                         {
2455                                 char s[k + 1];
2456                                 memcpy(s, t + 1, k);
2457                                 s[k] = 0;
2458
2459                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2460                                 if (r < 0)
2461                                         return r;
2462                         }
2463
2464                         if (n_array == (unsigned) -1) {
2465                                 types += k;
2466                                 n_struct -= k;
2467                         }
2468
2469                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2470                         if (r < 0)
2471                                 return r;
2472
2473                         types = t + 1;
2474                         n_struct = k;
2475                         n_array = va_arg(ap, unsigned);
2476
2477                         break;
2478                 }
2479
2480                 case SD_BUS_TYPE_VARIANT: {
2481                         const char *s;
2482
2483                         s = va_arg(ap, const char*);
2484                         if (!s)
2485                                 return -EINVAL;
2486
2487                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2488                         if (r < 0)
2489                                 return r;
2490
2491                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2492                         if (r < 0)
2493                                 return r;
2494
2495                         types = s;
2496                         n_struct = strlen(s);
2497                         n_array = (unsigned) -1;
2498
2499                         break;
2500                 }
2501
2502                 case SD_BUS_TYPE_STRUCT_BEGIN:
2503                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2504                         size_t k;
2505
2506                         r = signature_element_length(t, &k);
2507                         if (r < 0)
2508                                 return r;
2509
2510                         {
2511                                 char s[k - 1];
2512
2513                                 memcpy(s, t + 1, k - 2);
2514                                 s[k - 2] = 0;
2515
2516                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2517                                 if (r < 0)
2518                                         return r;
2519                         }
2520
2521                         if (n_array == (unsigned) -1) {
2522                                 types += k - 1;
2523                                 n_struct -= k - 1;
2524                         }
2525
2526                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2527                         if (r < 0)
2528                                 return r;
2529
2530                         types = t + 1;
2531                         n_struct = k - 2;
2532                         n_array = (unsigned) -1;
2533
2534                         break;
2535                 }
2536
2537                 default:
2538                         r = -EINVAL;
2539                 }
2540
2541                 if (r < 0)
2542                         return r;
2543         }
2544
2545         return 1;
2546 }
2547
2548 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2549         va_list ap;
2550         int r;
2551
2552         assert_return(m, -EINVAL);
2553         assert_return(types, -EINVAL);
2554         assert_return(!m->sealed, -EPERM);
2555         assert_return(!m->poisoned, -ESTALE);
2556
2557         va_start(ap, types);
2558         r = sd_bus_message_appendv(m, types, ap);
2559         va_end(ap);
2560
2561         return r;
2562 }
2563
2564 _public_ int sd_bus_message_append_array_space(
2565                 sd_bus_message *m,
2566                 char type,
2567                 size_t size,
2568                 void **ptr) {
2569
2570         ssize_t align, sz;
2571         void *a;
2572         int r;
2573
2574         assert_return(m, -EINVAL);
2575         assert_return(!m->sealed, -EPERM);
2576         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2577         assert_return(ptr || size == 0, -EINVAL);
2578         assert_return(!m->poisoned, -ESTALE);
2579
2580         /* alignment and size of the trivial types (except bool) is
2581          * identical for gvariant and dbus1 marshalling */
2582         align = bus_type_get_alignment(type);
2583         sz = bus_type_get_size(type);
2584
2585         assert_se(align > 0);
2586         assert_se(sz > 0);
2587
2588         if (size % sz != 0)
2589                 return -EINVAL;
2590
2591         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2592         if (r < 0)
2593                 return r;
2594
2595         a = message_extend_body(m, align, size, false, false);
2596         if (!a)
2597                 return -ENOMEM;
2598
2599         r = sd_bus_message_close_container(m);
2600         if (r < 0)
2601                 return r;
2602
2603         *ptr = a;
2604         return 0;
2605 }
2606
2607 _public_ int sd_bus_message_append_array(
2608                 sd_bus_message *m,
2609                 char type,
2610                 const void *ptr,
2611                 size_t size) {
2612         int r;
2613         void *p;
2614
2615         assert_return(m, -EINVAL);
2616         assert_return(!m->sealed, -EPERM);
2617         assert_return(bus_type_is_trivial(type), -EINVAL);
2618         assert_return(ptr || size == 0, -EINVAL);
2619         assert_return(!m->poisoned, -ESTALE);
2620
2621         r = sd_bus_message_append_array_space(m, type, size, &p);
2622         if (r < 0)
2623                 return r;
2624
2625         memcpy_safe(p, ptr, size);
2626
2627         return 0;
2628 }
2629
2630 _public_ int sd_bus_message_append_array_iovec(
2631                 sd_bus_message *m,
2632                 char type,
2633                 const struct iovec *iov,
2634                 unsigned n) {
2635
2636         size_t size;
2637         unsigned i;
2638         void *p;
2639         int r;
2640
2641         assert_return(m, -EINVAL);
2642         assert_return(!m->sealed, -EPERM);
2643         assert_return(bus_type_is_trivial(type), -EINVAL);
2644         assert_return(iov || n == 0, -EINVAL);
2645         assert_return(!m->poisoned, -ESTALE);
2646
2647         size = IOVEC_TOTAL_SIZE(iov, n);
2648
2649         r = sd_bus_message_append_array_space(m, type, size, &p);
2650         if (r < 0)
2651                 return r;
2652
2653         for (i = 0; i < n; i++) {
2654
2655                 if (iov[i].iov_base)
2656                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2657                 else
2658                         memzero(p, iov[i].iov_len);
2659
2660                 p = (uint8_t*) p + iov[i].iov_len;
2661         }
2662
2663         return 0;
2664 }
2665
2666 _public_ int sd_bus_message_append_array_memfd(
2667                 sd_bus_message *m,
2668                 char type,
2669                 int memfd,
2670                 uint64_t offset,
2671                 uint64_t size) {
2672
2673         _cleanup_close_ int copy_fd = -1;
2674         struct bus_body_part *part;
2675         ssize_t align, sz;
2676         uint64_t real_size;
2677         void *a;
2678         int r;
2679
2680         assert_return(m, -EINVAL);
2681         assert_return(memfd >= 0, -EBADF);
2682         assert_return(bus_type_is_trivial(type), -EINVAL);
2683         assert_return(size > 0, -EINVAL);
2684         assert_return(!m->sealed, -EPERM);
2685         assert_return(!m->poisoned, -ESTALE);
2686
2687         r = memfd_set_sealed(memfd);
2688         if (r < 0)
2689                 return r;
2690
2691         copy_fd = dup(memfd);
2692         if (copy_fd < 0)
2693                 return copy_fd;
2694
2695         r = memfd_get_size(memfd, &real_size);
2696         if (r < 0)
2697                 return r;
2698
2699         if (offset == 0 && size == (uint64_t) -1)
2700                 size = real_size;
2701         else if (offset + size > real_size)
2702                 return -EMSGSIZE;
2703
2704         align = bus_type_get_alignment(type);
2705         sz = bus_type_get_size(type);
2706
2707         assert_se(align > 0);
2708         assert_se(sz > 0);
2709
2710         if (offset % align != 0)
2711                 return -EINVAL;
2712
2713         if (size % sz != 0)
2714                 return -EINVAL;
2715
2716         if (size > (uint64_t) (uint32_t) -1)
2717                 return -EINVAL;
2718
2719         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2720         if (r < 0)
2721                 return r;
2722
2723         a = message_extend_body(m, align, 0, false, false);
2724         if (!a)
2725                 return -ENOMEM;
2726
2727         part = message_append_part(m);
2728         if (!part)
2729                 return -ENOMEM;
2730
2731         part->memfd = copy_fd;
2732         part->memfd_offset = offset;
2733         part->sealed = true;
2734         part->size = size;
2735         copy_fd = -1;
2736
2737         m->body_size += size;
2738         message_extend_containers(m, size);
2739
2740         return sd_bus_message_close_container(m);
2741 }
2742
2743 _public_ int sd_bus_message_append_string_memfd(
2744                 sd_bus_message *m,
2745                 int memfd,
2746                 uint64_t offset,
2747                 uint64_t size) {
2748
2749         _cleanup_close_ int copy_fd = -1;
2750         struct bus_body_part *part;
2751         struct bus_container *c;
2752         uint64_t real_size;
2753         void *a;
2754         int r;
2755
2756         assert_return(m, -EINVAL);
2757         assert_return(memfd >= 0, -EBADF);
2758         assert_return(size > 0, -EINVAL);
2759         assert_return(!m->sealed, -EPERM);
2760         assert_return(!m->poisoned, -ESTALE);
2761
2762         r = memfd_set_sealed(memfd);
2763         if (r < 0)
2764                 return r;
2765
2766         copy_fd = dup(memfd);
2767         if (copy_fd < 0)
2768                 return copy_fd;
2769
2770         r = memfd_get_size(memfd, &real_size);
2771         if (r < 0)
2772                 return r;
2773
2774         if (offset == 0 && size == (uint64_t) -1)
2775                 size = real_size;
2776         else if (offset + size > real_size)
2777                 return -EMSGSIZE;
2778
2779         /* We require this to be NUL terminated */
2780         if (size == 0)
2781                 return -EINVAL;
2782
2783         if (size > (uint64_t) (uint32_t) -1)
2784                 return -EINVAL;
2785
2786         c = message_get_container(m);
2787         if (c->signature && c->signature[c->index]) {
2788                 /* Container signature is already set */
2789
2790                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2791                         return -ENXIO;
2792         } else {
2793                 char *e;
2794
2795                 /* Maybe we can append to the signature? But only if this is the top-level container */
2796                 if (c->enclosing != 0)
2797                         return -ENXIO;
2798
2799                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2800                 if (!e) {
2801                         m->poisoned = true;
2802                         return -ENOMEM;
2803                 }
2804         }
2805
2806         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2807                 a = message_extend_body(m, 4, 4, false, false);
2808                 if (!a)
2809                         return -ENOMEM;
2810
2811                 *(uint32_t*) a = size - 1;
2812         }
2813
2814         part = message_append_part(m);
2815         if (!part)
2816                 return -ENOMEM;
2817
2818         part->memfd = copy_fd;
2819         part->memfd_offset = offset;
2820         part->sealed = true;
2821         part->size = size;
2822         copy_fd = -1;
2823
2824         m->body_size += size;
2825         message_extend_containers(m, size);
2826
2827         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2828                 r = message_add_offset(m, m->body_size);
2829                 if (r < 0) {
2830                         m->poisoned = true;
2831                         return -ENOMEM;
2832                 }
2833         }
2834
2835         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2836                 c->index++;
2837
2838         return 0;
2839 }
2840
2841 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2842         char **i;
2843         int r;
2844
2845         assert_return(m, -EINVAL);
2846         assert_return(!m->sealed, -EPERM);
2847         assert_return(!m->poisoned, -ESTALE);
2848
2849         r = sd_bus_message_open_container(m, 'a', "s");
2850         if (r < 0)
2851                 return r;
2852
2853         STRV_FOREACH(i, l) {
2854                 r = sd_bus_message_append_basic(m, 's', *i);
2855                 if (r < 0)
2856                         return r;
2857         }
2858
2859         return sd_bus_message_close_container(m);
2860 }
2861
2862 static int bus_message_close_header(sd_bus_message *m) {
2863
2864         assert(m);
2865
2866         /* The actual user data is finished now, we just complete the
2867            variant and struct now (at least on gvariant). Remember
2868            this position, so that during parsing we know where to
2869            put the outer container end. */
2870         m->user_body_size = m->body_size;
2871
2872         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2873                 const char *signature;
2874                 size_t sz, l;
2875                 void *d;
2876
2877                 /* Add offset table to end of fields array */
2878                 if (m->n_header_offsets >= 1) {
2879                         uint8_t *a;
2880                         unsigned i;
2881
2882                         assert(m->fields_size == m->header_offsets[m->n_header_offsets-1]);
2883
2884                         sz = bus_gvariant_determine_word_size(m->fields_size, m->n_header_offsets);
2885                         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2886                         if (!a)
2887                                 return -ENOMEM;
2888
2889                         for (i = 0; i < m->n_header_offsets; i++)
2890                                 bus_gvariant_write_word_le(a + sz*i, sz, m->header_offsets[i]);
2891                 }
2892
2893                 /* Add gvariant NUL byte plus signature to the end of
2894                  * the body, followed by the final offset pointing to
2895                  * the end of the fields array */
2896
2897                 signature = strempty(m->root_container.signature);
2898                 l = strlen(signature);
2899
2900                 sz = bus_gvariant_determine_word_size(sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size + 1 + l + 2, 1);
2901                 d = message_extend_body(m, 1, 1 + l + 2 + sz, false, true);
2902                 if (!d)
2903                         return -ENOMEM;
2904
2905                 *(uint8_t*) d = 0;
2906                 *((uint8_t*) d + 1) = SD_BUS_TYPE_STRUCT_BEGIN;
2907                 memcpy((uint8_t*) d + 2, signature, l);
2908                 *((uint8_t*) d + 1 + l + 1) = SD_BUS_TYPE_STRUCT_END;
2909
2910                 bus_gvariant_write_word_le((uint8_t*) d + 1 + l + 2, sz, sizeof(struct bus_header) + m->fields_size);
2911
2912                 m->footer = d;
2913                 m->footer_accessible = 1 + l + 2 + sz;
2914         } else {
2915                 m->header->dbus1.fields_size = m->fields_size;
2916                 m->header->dbus1.body_size = m->body_size;
2917         }
2918
2919         return 0;
2920 }
2921
2922 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2923         struct bus_body_part *part;
2924         size_t a;
2925         unsigned i;
2926         int r;
2927
2928         assert(m);
2929
2930         if (m->sealed)
2931                 return -EPERM;
2932
2933         if (m->n_containers > 0)
2934                 return -EBADMSG;
2935
2936         if (m->poisoned)
2937                 return -ESTALE;
2938
2939         if (cookie > 0xffffffffULL &&
2940             !BUS_MESSAGE_IS_GVARIANT(m))
2941                 return -EOPNOTSUPP;
2942
2943         /* In vtables the return signature of method calls is listed,
2944          * let's check if they match if this is a response */
2945         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2946             m->enforced_reply_signature &&
2947             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2948                 return -ENOMSG;
2949
2950         /* If gvariant marshalling is used we need to close the body structure */
2951         r = bus_message_close_struct(m, &m->root_container, false);
2952         if (r < 0)
2953                 return r;
2954
2955         /* If there's a non-trivial signature set, then add it in
2956          * here, but only on dbus1 */
2957         if (!isempty(m->root_container.signature) && !BUS_MESSAGE_IS_GVARIANT(m)) {
2958                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2959                 if (r < 0)
2960                         return r;
2961         }
2962
2963         if (m->n_fds > 0) {
2964                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2965                 if (r < 0)
2966                         return r;
2967         }
2968
2969         r = bus_message_close_header(m);
2970         if (r < 0)
2971                 return r;
2972
2973         if (BUS_MESSAGE_IS_GVARIANT(m))
2974                 m->header->dbus2.cookie = cookie;
2975         else
2976                 m->header->dbus1.serial = (uint32_t) cookie;
2977
2978         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2979
2980         /* Add padding at the end of the fields part, since we know
2981          * the body needs to start at an 8 byte alignment. We made
2982          * sure we allocated enough space for this, so all we need to
2983          * do here is to zero it out. */
2984         a = ALIGN8(m->fields_size) - m->fields_size;
2985         if (a > 0)
2986                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + m->fields_size, a);
2987
2988         /* If this is something we can send as memfd, then let's seal
2989         the memfd now. Note that we can send memfds as payload only
2990         for directed messages, and not for broadcasts. */
2991         if (m->destination && m->bus->use_memfd) {
2992                 MESSAGE_FOREACH_PART(part, i, m)
2993                         if (part->memfd >= 0 &&
2994                             !part->sealed &&
2995                             (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0) &&
2996                             part != m->body_end) { /* The last part may never be sent as memfd */
2997                                 uint64_t sz;
2998
2999                                 /* Try to seal it if that makes
3000                                  * sense. First, unmap our own map to
3001                                  * make sure we don't keep it busy. */
3002                                 bus_body_part_unmap(part);
3003
3004                                 /* Then, sync up real memfd size */
3005                                 sz = part->size;
3006                                 r = memfd_set_size(part->memfd, sz);
3007                                 if (r < 0)
3008                                         return r;
3009
3010                                 /* Finally, try to seal */
3011                                 if (memfd_set_sealed(part->memfd) >= 0)
3012                                         part->sealed = true;
3013                         }
3014         }
3015
3016         m->root_container.end = m->user_body_size;
3017         m->root_container.index = 0;
3018         m->root_container.offset_index = 0;
3019         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
3020
3021         m->sealed = true;
3022
3023         return 0;
3024 }
3025
3026 int bus_body_part_map(struct bus_body_part *part) {
3027         void *p;
3028         size_t psz, shift;
3029
3030         assert_se(part);
3031
3032         if (part->data)
3033                 return 0;
3034
3035         if (part->size <= 0)
3036                 return 0;
3037
3038         /* For smaller zero parts (as used for padding) we don't need to map anything... */
3039         if (part->memfd < 0 && part->is_zero && part->size < 8) {
3040                 static const uint8_t zeroes[7] = { };
3041                 part->data = (void*) zeroes;
3042                 return 0;
3043         }
3044
3045         shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
3046         psz = PAGE_ALIGN(part->size + shift);
3047
3048         if (part->memfd >= 0)
3049                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
3050         else if (part->is_zero)
3051                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3052         else
3053                 return -EINVAL;
3054
3055         if (p == MAP_FAILED)
3056                 return -errno;
3057
3058         part->mapped = psz;
3059         part->mmap_begin = p;
3060         part->data = (uint8_t*) p + shift;
3061         part->munmap_this = true;
3062
3063         return 0;
3064 }
3065
3066 void bus_body_part_unmap(struct bus_body_part *part) {
3067
3068         assert_se(part);
3069
3070         if (part->memfd < 0)
3071                 return;
3072
3073         if (!part->mmap_begin)
3074                 return;
3075
3076         if (!part->munmap_this)
3077                 return;
3078
3079         assert_se(munmap(part->mmap_begin, part->mapped) == 0);
3080
3081         part->mmap_begin = NULL;
3082         part->data = NULL;
3083         part->mapped = 0;
3084         part->munmap_this = false;
3085
3086         return;
3087 }
3088
3089 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
3090         size_t k, start, end;
3091
3092         assert(rindex);
3093         assert(align > 0);
3094
3095         start = ALIGN_TO((size_t) *rindex, align);
3096         end = start + nbytes;
3097
3098         if (end > sz)
3099                 return -EBADMSG;
3100
3101         /* Verify that padding is 0 */
3102         for (k = *rindex; k < start; k++)
3103                 if (((const uint8_t*) p)[k] != 0)
3104                         return -EBADMSG;
3105
3106         if (r)
3107                 *r = (uint8_t*) p + start;
3108
3109         *rindex = end;
3110
3111         return 1;
3112 }
3113
3114 static bool message_end_of_signature(sd_bus_message *m) {
3115         struct bus_container *c;
3116
3117         assert(m);
3118
3119         c = message_get_container(m);
3120         return !c->signature || c->signature[c->index] == 0;
3121 }
3122
3123 static bool message_end_of_array(sd_bus_message *m, size_t index) {
3124         struct bus_container *c;
3125
3126         assert(m);
3127
3128         c = message_get_container(m);
3129         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3130                 return false;
3131
3132         if (BUS_MESSAGE_IS_GVARIANT(m))
3133                 return index >= c->end;
3134         else {
3135                 assert(c->array_size);
3136                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
3137         }
3138 }
3139
3140 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
3141         assert_return(m, -EINVAL);
3142         assert_return(m->sealed, -EPERM);
3143
3144         if (complete && m->n_containers > 0)
3145                 return false;
3146
3147         if (message_end_of_signature(m))
3148                 return true;
3149
3150         if (message_end_of_array(m, m->rindex))
3151                 return true;
3152
3153         return false;
3154 }
3155
3156 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
3157         struct bus_body_part *part;
3158         size_t begin;
3159         int r;
3160
3161         assert(m);
3162
3163         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
3164                 part = m->cached_rindex_part;
3165                 begin = m->cached_rindex_part_begin;
3166         } else {
3167                 part = &m->body;
3168                 begin = 0;
3169         }
3170
3171         while (part) {
3172                 if (index < begin)
3173                         return NULL;
3174
3175                 if (index + sz <= begin + part->size) {
3176
3177                         r = bus_body_part_map(part);
3178                         if (r < 0)
3179                                 return NULL;
3180
3181                         if (p)
3182                                 *p = (uint8_t*) part->data + index - begin;
3183
3184                         m->cached_rindex_part = part;
3185                         m->cached_rindex_part_begin = begin;
3186
3187                         return part;
3188                 }
3189
3190                 begin += part->size;
3191                 part = part->next;
3192         }
3193
3194         return NULL;
3195 }
3196
3197 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3198         int r;
3199
3200         assert(m);
3201         assert(c);
3202         assert(rindex);
3203
3204         if (!BUS_MESSAGE_IS_GVARIANT(m))
3205                 return 0;
3206
3207         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3208                 int sz;
3209
3210                 sz = bus_gvariant_get_size(c->signature);
3211                 if (sz < 0) {
3212                         int alignment;
3213
3214                         if (c->offset_index+1 >= c->n_offsets)
3215                                 goto end;
3216
3217                         /* Variable-size array */
3218
3219                         alignment = bus_gvariant_get_alignment(c->signature);
3220                         assert(alignment > 0);
3221
3222                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3223                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3224                 } else {
3225
3226                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3227                                 goto end;
3228
3229                         /* Fixed-size array */
3230                         *rindex = c->begin + (c->offset_index+1) * sz;
3231                         c->item_size = sz;
3232                 }
3233
3234                 c->offset_index++;
3235
3236         } else if (IN_SET(c->enclosing, 0, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY)) {
3237
3238                 int alignment;
3239                 size_t n, j;
3240
3241                 if (c->offset_index+1 >= c->n_offsets)
3242                         goto end;
3243
3244                 r = signature_element_length(c->signature + c->index, &n);
3245                 if (r < 0)
3246                         return r;
3247
3248                 r = signature_element_length(c->signature + c->index + n, &j);
3249                 if (r < 0)
3250                         return r;
3251                 else {
3252                         char t[j+1];
3253                         memcpy(t, c->signature + c->index + n, j);
3254                         t[j] = 0;
3255
3256                         alignment = bus_gvariant_get_alignment(t);
3257                 }
3258
3259                 assert(alignment > 0);
3260
3261                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3262                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3263
3264                 c->offset_index++;
3265
3266         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3267                 goto end;
3268         else
3269                 assert_not_reached("Unknown container type");
3270
3271         return 0;
3272
3273 end:
3274         /* Reached the end */
3275         *rindex = c->end;
3276         c->item_size = 0;
3277         return 0;
3278 }
3279
3280
3281 static int message_peek_body(
3282                 sd_bus_message *m,
3283                 size_t *rindex,
3284                 size_t align,
3285                 size_t nbytes,
3286                 void **ret) {
3287
3288         size_t k, start, end, padding;
3289         struct bus_body_part *part;
3290         uint8_t *q;
3291
3292         assert(m);
3293         assert(rindex);
3294         assert(align > 0);
3295
3296         start = ALIGN_TO((size_t) *rindex, align);
3297         padding = start - *rindex;
3298         end = start + nbytes;
3299
3300         if (end > m->user_body_size)
3301                 return -EBADMSG;
3302
3303         part = find_part(m, *rindex, padding, (void**) &q);
3304         if (!part)
3305                 return -EBADMSG;
3306
3307         if (q) {
3308                 /* Verify padding */
3309                 for (k = 0; k < padding; k++)
3310                         if (q[k] != 0)
3311                                 return -EBADMSG;
3312         }
3313
3314         part = find_part(m, start, nbytes, (void**) &q);
3315         if (!part || (nbytes > 0 && !q))
3316                 return -EBADMSG;
3317
3318         *rindex = end;
3319
3320         if (ret)
3321                 *ret = q;
3322
3323         return 0;
3324 }
3325
3326 static bool validate_nul(const char *s, size_t l) {
3327
3328         /* Check for NUL chars in the string */
3329         if (memchr(s, 0, l))
3330                 return false;
3331
3332         /* Check for NUL termination */
3333         if (s[l] != 0)
3334                 return false;
3335
3336         return true;
3337 }
3338
3339 static bool validate_string(const char *s, size_t l) {
3340
3341         if (!validate_nul(s, l))
3342                 return false;
3343
3344         /* Check if valid UTF8 */
3345         if (!utf8_is_valid(s))
3346                 return false;
3347
3348         return true;
3349 }
3350
3351 static bool validate_signature(const char *s, size_t l) {
3352
3353         if (!validate_nul(s, l))
3354                 return false;
3355
3356         /* Check if valid signature */
3357         if (!signature_is_valid(s, true))
3358                 return false;
3359
3360         return true;
3361 }
3362
3363 static bool validate_object_path(const char *s, size_t l) {
3364
3365         if (!validate_nul(s, l))
3366                 return false;
3367
3368         if (!object_path_is_valid(s))
3369                 return false;
3370
3371         return true;
3372 }
3373
3374 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3375         struct bus_container *c;
3376         size_t rindex;
3377         void *q;
3378         int r;
3379
3380         assert_return(m, -EINVAL);
3381         assert_return(m->sealed, -EPERM);
3382         assert_return(bus_type_is_basic(type), -EINVAL);
3383
3384         if (message_end_of_signature(m))
3385                 return -ENXIO;
3386
3387         if (message_end_of_array(m, m->rindex))
3388                 return 0;
3389
3390         c = message_get_container(m);
3391         if (c->signature[c->index] != type)
3392                 return -ENXIO;
3393
3394         rindex = m->rindex;
3395
3396         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3397
3398                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3399                         bool ok;
3400
3401                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3402                         if (r < 0)
3403                                 return r;
3404
3405                         if (type == SD_BUS_TYPE_STRING)
3406                                 ok = validate_string(q, c->item_size-1);
3407                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3408                                 ok = validate_object_path(q, c->item_size-1);
3409                         else
3410                                 ok = validate_signature(q, c->item_size-1);
3411
3412                         if (!ok)
3413                                 return -EBADMSG;
3414
3415                         if (p)
3416                                 *(const char**) p = q;
3417                 } else {
3418                         int sz, align;
3419
3420                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3421                         assert(sz > 0);
3422                         if ((size_t) sz != c->item_size)
3423                                 return -EBADMSG;
3424
3425                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3426                         assert(align > 0);
3427
3428                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3429                         if (r < 0)
3430                                 return r;
3431
3432                         switch (type) {
3433
3434                         case SD_BUS_TYPE_BYTE:
3435                                 if (p)
3436                                         *(uint8_t*) p = *(uint8_t*) q;
3437                                 break;
3438
3439                         case SD_BUS_TYPE_BOOLEAN:
3440                                 if (p)
3441                                         *(int*) p = !!*(uint8_t*) q;
3442                                 break;
3443
3444                         case SD_BUS_TYPE_INT16:
3445                         case SD_BUS_TYPE_UINT16:
3446                                 if (p)
3447                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3448                                 break;
3449
3450                         case SD_BUS_TYPE_INT32:
3451                         case SD_BUS_TYPE_UINT32:
3452                                 if (p)
3453                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3454                                 break;
3455
3456                         case SD_BUS_TYPE_INT64:
3457                         case SD_BUS_TYPE_UINT64:
3458                         case SD_BUS_TYPE_DOUBLE:
3459                                 if (p)
3460                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3461                                 break;
3462
3463                         case SD_BUS_TYPE_UNIX_FD: {
3464                                 uint32_t j;
3465
3466                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3467                                 if (j >= m->n_fds)
3468                                         return -EBADMSG;
3469
3470                                 if (p)
3471                                         *(int*) p = m->fds[j];
3472
3473                                 break;
3474                         }
3475
3476                         default:
3477                                 assert_not_reached("unexpected type");
3478                         }
3479                 }
3480
3481                 r = container_next_item(m, c, &rindex);
3482                 if (r < 0)
3483                         return r;
3484         } else {
3485
3486                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3487                         uint32_t l;
3488                         bool ok;
3489
3490                         r = message_peek_body(m, &rindex, 4, 4, &q);
3491                         if (r < 0)
3492                                 return r;
3493
3494                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3495                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3496                         if (r < 0)
3497                                 return r;
3498
3499                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3500                                 ok = validate_object_path(q, l);
3501                         else
3502                                 ok = validate_string(q, l);
3503                         if (!ok)
3504                                 return -EBADMSG;
3505
3506                         if (p)
3507                                 *(const char**) p = q;
3508
3509                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3510                         uint8_t l;
3511
3512                         r = message_peek_body(m, &rindex, 1, 1, &q);
3513                         if (r < 0)
3514                                 return r;
3515
3516                         l = *(uint8_t*) q;
3517                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3518                         if (r < 0)
3519                                 return r;
3520
3521                         if (!validate_signature(q, l))
3522                                 return -EBADMSG;
3523
3524                         if (p)
3525                                 *(const char**) p = q;
3526
3527                 } else {
3528                         ssize_t sz, align;
3529
3530                         align = bus_type_get_alignment(type);
3531                         assert(align > 0);
3532
3533                         sz = bus_type_get_size(type);
3534                         assert(sz > 0);
3535
3536                         r = message_peek_body(m, &rindex, align, sz, &q);
3537                         if (r < 0)
3538                                 return r;
3539
3540                         switch (type) {
3541
3542                         case SD_BUS_TYPE_BYTE:
3543                                 if (p)
3544                                         *(uint8_t*) p = *(uint8_t*) q;
3545                                 break;
3546
3547                         case SD_BUS_TYPE_BOOLEAN:
3548                                 if (p)
3549                                         *(int*) p = !!*(uint32_t*) q;
3550                                 break;
3551
3552                         case SD_BUS_TYPE_INT16:
3553                         case SD_BUS_TYPE_UINT16:
3554                                 if (p)
3555                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3556                                 break;
3557
3558                         case SD_BUS_TYPE_INT32:
3559                         case SD_BUS_TYPE_UINT32:
3560                                 if (p)
3561                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3562                                 break;
3563
3564                         case SD_BUS_TYPE_INT64:
3565                         case SD_BUS_TYPE_UINT64:
3566                         case SD_BUS_TYPE_DOUBLE:
3567                                 if (p)
3568                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3569                                 break;
3570
3571                         case SD_BUS_TYPE_UNIX_FD: {
3572                                 uint32_t j;
3573
3574                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3575                                 if (j >= m->n_fds)
3576                                         return -EBADMSG;
3577
3578                                 if (p)
3579                                         *(int*) p = m->fds[j];
3580                                 break;
3581                         }
3582
3583                         default:
3584                                 assert_not_reached("Unknown basic type...");
3585                         }
3586                 }
3587         }
3588
3589         m->rindex = rindex;
3590
3591         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3592                 c->index++;
3593
3594         return 1;
3595 }
3596
3597 static int bus_message_enter_array(
3598                 sd_bus_message *m,
3599                 struct bus_container *c,
3600                 const char *contents,
3601                 uint32_t **array_size,
3602                 size_t *item_size,
3603                 size_t **offsets,
3604                 size_t *n_offsets) {
3605
3606         size_t rindex;
3607         void *q;
3608         int r, alignment;
3609
3610         assert(m);
3611         assert(c);
3612         assert(contents);
3613         assert(array_size);
3614         assert(item_size);
3615         assert(offsets);
3616         assert(n_offsets);
3617
3618         if (!signature_is_single(contents, true))
3619                 return -EINVAL;
3620
3621         if (!c->signature || c->signature[c->index] == 0)
3622                 return -ENXIO;
3623
3624         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3625                 return -ENXIO;
3626
3627         if (!startswith(c->signature + c->index + 1, contents))
3628                 return -ENXIO;
3629
3630         rindex = m->rindex;
3631
3632         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3633                 /* dbus1 */
3634
3635                 r = message_peek_body(m, &rindex, 4, 4, &q);
3636                 if (r < 0)
3637                         return r;
3638
3639                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3640                         return -EBADMSG;
3641
3642                 alignment = bus_type_get_alignment(contents[0]);
3643                 if (alignment < 0)
3644                         return alignment;
3645
3646                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3647                 if (r < 0)
3648                         return r;
3649
3650                 *array_size = (uint32_t*) q;
3651
3652         } else if (c->item_size <= 0) {
3653
3654                 /* gvariant: empty array */
3655                 *item_size = 0;
3656                 *offsets = NULL;
3657                 *n_offsets = 0;
3658
3659         } else if (bus_gvariant_is_fixed_size(contents)) {
3660
3661                 /* gvariant: fixed length array */
3662                 *item_size = bus_gvariant_get_size(contents);
3663                 *offsets = NULL;
3664                 *n_offsets = 0;
3665
3666         } else {
3667                 size_t where, p = 0, framing, sz;
3668                 unsigned i;
3669
3670                 /* gvariant: variable length array */
3671                 sz = bus_gvariant_determine_word_size(c->item_size, 0);
3672
3673                 where = rindex + c->item_size - sz;
3674                 r = message_peek_body(m, &where, 1, sz, &q);
3675                 if (r < 0)
3676                         return r;
3677
3678                 framing = bus_gvariant_read_word_le(q, sz);
3679                 if (framing > c->item_size - sz)
3680                         return -EBADMSG;
3681                 if ((c->item_size - framing) % sz != 0)
3682                         return -EBADMSG;
3683
3684                 *n_offsets = (c->item_size - framing) / sz;
3685
3686                 where = rindex + framing;
3687                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3688                 if (r < 0)
3689                         return r;
3690
3691                 *offsets = new(size_t, *n_offsets);
3692                 if (!*offsets)
3693                         return -ENOMEM;
3694
3695                 for (i = 0; i < *n_offsets; i++) {
3696                         size_t x;
3697
3698                         x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
3699                         if (x > c->item_size - sz)
3700                                 return -EBADMSG;
3701                         if (x < p)
3702                                 return -EBADMSG;
3703
3704                         (*offsets)[i] = rindex + x;
3705                         p = x;
3706                 }
3707
3708                 *item_size = (*offsets)[0] - rindex;
3709         }
3710
3711         m->rindex = rindex;
3712
3713         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3714                 c->index += 1 + strlen(contents);
3715
3716         return 1;
3717 }
3718
3719 static int bus_message_enter_variant(
3720                 sd_bus_message *m,
3721                 struct bus_container *c,
3722                 const char *contents,
3723                 size_t *item_size) {
3724
3725         size_t rindex;
3726         uint8_t l;
3727         void *q;
3728         int r;
3729
3730         assert(m);
3731         assert(c);
3732         assert(contents);
3733         assert(item_size);
3734
3735         if (!signature_is_single(contents, false))
3736                 return -EINVAL;
3737
3738         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3739                 return -EINVAL;
3740
3741         if (!c->signature || c->signature[c->index] == 0)
3742                 return -ENXIO;
3743
3744         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3745                 return -ENXIO;
3746
3747         rindex = m->rindex;
3748
3749         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3750                 size_t k, where;
3751
3752                 k = strlen(contents);
3753                 if (1+k > c->item_size)
3754                         return -EBADMSG;
3755
3756                 where = rindex + c->item_size - (1+k);
3757                 r = message_peek_body(m, &where, 1, 1+k, &q);
3758                 if (r < 0)
3759                         return r;
3760
3761                 if (*(char*) q != 0)
3762                         return -EBADMSG;
3763
3764                 if (memcmp((uint8_t*) q+1, contents, k))
3765                         return -ENXIO;
3766
3767                 *item_size = c->item_size - (1+k);
3768
3769         } else {
3770                 r = message_peek_body(m, &rindex, 1, 1, &q);
3771                 if (r < 0)
3772                         return r;
3773
3774                 l = *(uint8_t*) q;
3775                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3776                 if (r < 0)
3777                         return r;
3778
3779                 if (!validate_signature(q, l))
3780                         return -EBADMSG;
3781
3782                 if (!streq(q, contents))
3783                         return -ENXIO;
3784         }
3785
3786         m->rindex = rindex;
3787
3788         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3789                 c->index++;
3790
3791         return 1;
3792 }
3793
3794 static int build_struct_offsets(
3795                 sd_bus_message *m,
3796                 const char *signature,
3797                 size_t size,
3798                 size_t *item_size,
3799                 size_t **offsets,
3800                 size_t *n_offsets) {
3801
3802         unsigned n_variable = 0, n_total = 0, v;
3803         size_t previous = 0, where;
3804         const char *p;
3805         size_t sz;
3806         void *q;
3807         int r;
3808
3809         assert(m);
3810         assert(item_size);
3811         assert(offsets);
3812         assert(n_offsets);
3813
3814         if (isempty(signature)) {
3815                 /* Unary type is encoded as *fixed* 1 byte padding */
3816                 r = message_peek_body(m, &m->rindex, 1, 1, &q);
3817                 if (r < 0)
3818                         return r;
3819
3820                 if (*(uint8_t *) q != 0)
3821                         return -EBADMSG;
3822
3823                 *item_size = 0;
3824                 *offsets = NULL;
3825                 *n_offsets = 0;
3826                 return 0;
3827         }
3828
3829         sz = bus_gvariant_determine_word_size(size, 0);
3830         if (sz <= 0)
3831                 return -EBADMSG;
3832
3833         /* First, loop over signature and count variable elements and
3834          * elements in general. We use this to know how large the
3835          * offset array is at the end of the structure. Note that
3836          * GVariant only stores offsets for all variable size elements
3837          * that are not the last item. */
3838
3839         p = signature;
3840         while (*p != 0) {
3841                 size_t n;
3842
3843                 r = signature_element_length(p, &n);
3844                 if (r < 0)
3845                         return r;
3846                 else {
3847                         char t[n+1];
3848
3849                         memcpy(t, p, n);
3850                         t[n] = 0;
3851
3852                         r = bus_gvariant_is_fixed_size(t);
3853                 }
3854
3855                 if (r < 0)
3856                         return r;
3857                 if (r == 0 && p[n] != 0) /* except the last item */
3858                         n_variable++;
3859                 n_total++;
3860
3861                 p += n;
3862         }
3863
3864         if (size < n_variable * sz)
3865                 return -EBADMSG;
3866
3867         where = m->rindex + size - (n_variable * sz);
3868         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3869         if (r < 0)
3870                 return r;
3871
3872         v = n_variable;
3873
3874         *offsets = new(size_t, n_total);
3875         if (!*offsets)
3876                 return -ENOMEM;
3877
3878         *n_offsets = 0;
3879
3880         /* Second, loop again and build an offset table */
3881         p = signature;
3882         while (*p != 0) {
3883                 size_t n, offset;
3884                 int k;
3885
3886                 r = signature_element_length(p, &n);
3887                 if (r < 0)
3888                         return r;
3889                 else {
3890                         char t[n+1];
3891
3892                         memcpy(t, p, n);
3893                         t[n] = 0;
3894
3895                         k = bus_gvariant_get_size(t);
3896                         if (k < 0) {
3897                                 size_t x;
3898
3899                                 /* variable size */
3900                                 if (v > 0) {
3901                                         v--;
3902
3903                                         x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
3904                                         if (x >= size)
3905                                                 return -EBADMSG;
3906                                         if (m->rindex + x < previous)
3907                                                 return -EBADMSG;
3908                                 } else
3909                                         /* The last item's end
3910                                          * is determined from
3911                                          * the start of the
3912                                          * offset array */
3913                                         x = size - (n_variable * sz);
3914
3915                                 offset = m->rindex + x;
3916
3917                         } else {
3918                                 size_t align;
3919
3920                                 /* fixed size */
3921                                 align = bus_gvariant_get_alignment(t);
3922                                 assert(align > 0);
3923
3924                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3925                         }
3926                 }
3927
3928                 previous = (*offsets)[(*n_offsets)++] = offset;
3929                 p += n;
3930         }
3931
3932         assert(v == 0);
3933         assert(*n_offsets == n_total);
3934
3935         *item_size = (*offsets)[0] - m->rindex;
3936         return 0;
3937 }
3938
3939 static int enter_struct_or_dict_entry(
3940                 sd_bus_message *m,
3941                 struct bus_container *c,
3942                 const char *contents,
3943                 size_t *item_size,
3944                 size_t **offsets,
3945                 size_t *n_offsets) {
3946
3947         int r;
3948
3949         assert(m);
3950         assert(c);
3951         assert(contents);
3952         assert(item_size);
3953         assert(offsets);
3954         assert(n_offsets);
3955
3956         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3957
3958                 /* dbus1 */
3959                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3960                 if (r < 0)
3961                         return r;
3962
3963         } else
3964                 /* gvariant with contents */
3965                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3966
3967         return 0;
3968 }
3969
3970 static int bus_message_enter_struct(
3971                 sd_bus_message *m,
3972                 struct bus_container *c,
3973                 const char *contents,
3974                 size_t *item_size,
3975                 size_t **offsets,
3976                 size_t *n_offsets) {
3977
3978         size_t l;
3979         int r;
3980
3981         assert(m);
3982         assert(c);
3983         assert(contents);
3984         assert(item_size);
3985         assert(offsets);
3986         assert(n_offsets);
3987
3988         if (!signature_is_valid(contents, false))
3989                 return -EINVAL;
3990
3991         if (!c->signature || c->signature[c->index] == 0)
3992                 return -ENXIO;
3993
3994         l = strlen(contents);
3995
3996         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3997             !startswith(c->signature + c->index + 1, contents) ||
3998             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3999                 return -ENXIO;
4000
4001         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4002         if (r < 0)
4003                 return r;
4004
4005         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4006                 c->index += 1 + l + 1;
4007
4008         return 1;
4009 }
4010
4011 static int bus_message_enter_dict_entry(
4012                 sd_bus_message *m,
4013                 struct bus_container *c,
4014                 const char *contents,
4015                 size_t *item_size,
4016                 size_t **offsets,
4017                 size_t *n_offsets) {
4018
4019         size_t l;
4020         int r;
4021
4022         assert(m);
4023         assert(c);
4024         assert(contents);
4025
4026         if (!signature_is_pair(contents))
4027                 return -EINVAL;
4028
4029         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4030                 return -ENXIO;
4031
4032         if (!c->signature || c->signature[c->index] == 0)
4033                 return 0;
4034
4035         l = strlen(contents);
4036
4037         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
4038             !startswith(c->signature + c->index + 1, contents) ||
4039             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
4040                 return -ENXIO;
4041
4042         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4043         if (r < 0)
4044                 return r;
4045
4046         if (c->enclosing != SD_BUS_TYPE_ARRAY)
4047                 c->index += 1 + l + 1;
4048
4049         return 1;
4050 }
4051
4052 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
4053                                             char type,
4054                                             const char *contents) {
4055         struct bus_container *c, *w;
4056         uint32_t *array_size = NULL;
4057         char *signature;
4058         size_t before;
4059         size_t *offsets = NULL;
4060         size_t n_offsets = 0, item_size = 0;
4061         int r;
4062
4063         assert_return(m, -EINVAL);
4064         assert_return(m->sealed, -EPERM);
4065         assert_return(type != 0 || !contents, -EINVAL);
4066
4067         if (type == 0 || !contents) {
4068                 const char *cc;
4069                 char tt;
4070
4071                 /* Allow entering into anonymous containers */
4072                 r = sd_bus_message_peek_type(m, &tt, &cc);
4073                 if (r < 0)
4074                         return r;
4075
4076                 if (type != 0 && type != tt)
4077                         return -ENXIO;
4078
4079                 if (contents && !streq(contents, cc))
4080                         return -ENXIO;
4081
4082                 type = tt;
4083                 contents = cc;
4084         }
4085
4086         /*
4087          * We enforce a global limit on container depth, that is much
4088          * higher than the 32 structs and 32 arrays the specification
4089          * mandates. This is simpler to implement for us, and we need
4090          * this only to ensure our container array doesn't grow
4091          * without bounds. We are happy to return any data from a
4092          * message as long as the data itself is valid, even if the
4093          * overall message might be not.
4094          *
4095          * Note that the message signature is validated when
4096          * parsing the headers, and that validation does check the
4097          * 32/32 limit.
4098          *
4099          * Note that the specification defines no limits on the depth
4100          * of stacked variants, but we do.
4101          */
4102         if (m->n_containers >= BUS_CONTAINER_DEPTH)
4103                 return -EBADMSG;
4104
4105         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
4106                 return -ENOMEM;
4107
4108         if (message_end_of_signature(m))
4109                 return -ENXIO;
4110
4111         if (message_end_of_array(m, m->rindex))
4112                 return 0;
4113
4114         c = message_get_container(m);
4115
4116         signature = strdup(contents);
4117         if (!signature)
4118                 return -ENOMEM;
4119
4120         c->saved_index = c->index;
4121         before = m->rindex;
4122
4123         if (type == SD_BUS_TYPE_ARRAY)
4124                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
4125         else if (type == SD_BUS_TYPE_VARIANT)
4126                 r = bus_message_enter_variant(m, c, contents, &item_size);
4127         else if (type == SD_BUS_TYPE_STRUCT)
4128                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
4129         else if (type == SD_BUS_TYPE_DICT_ENTRY)
4130                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
4131         else
4132                 r = -EINVAL;
4133
4134         if (r <= 0) {
4135                 free(signature);
4136                 free(offsets);
4137                 return r;
4138         }
4139
4140         /* OK, let's fill it in */
4141         w = m->containers + m->n_containers++;
4142         w->enclosing = type;
4143         w->signature = signature;
4144         w->peeked_signature = NULL;
4145         w->index = 0;
4146
4147         w->before = before;
4148         w->begin = m->rindex;
4149
4150         /* Unary type has fixed size of 1, but virtual size of 0 */
4151         if (BUS_MESSAGE_IS_GVARIANT(m) &&
4152             type == SD_BUS_TYPE_STRUCT &&
4153             isempty(signature))
4154                 w->end = m->rindex + 0;
4155         else
4156                 w->end = m->rindex + c->item_size;
4157
4158         w->array_size = array_size;
4159         w->item_size = item_size;
4160         w->offsets = offsets;
4161         w->n_offsets = n_offsets;
4162         w->offset_index = 0;
4163
4164         return 1;
4165 }
4166
4167 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
4168         struct bus_container *c;
4169         unsigned saved;
4170         int r;
4171
4172         assert_return(m, -EINVAL);
4173         assert_return(m->sealed, -EPERM);
4174         assert_return(m->n_containers > 0, -ENXIO);
4175
4176         c = message_get_container(m);
4177
4178         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
4179                 if (c->signature && c->signature[c->index] != 0)
4180                         return -EBUSY;
4181         }
4182
4183         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4184                 if (m->rindex < c->end)
4185                         return -EBUSY;
4186
4187         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
4188                 uint32_t l;
4189
4190                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4191                 if (c->begin + l != m->rindex)
4192                         return -EBUSY;
4193         }
4194
4195         free(c->signature);
4196         free(c->peeked_signature);
4197         free(c->offsets);
4198         m->n_containers--;
4199
4200         c = message_get_container(m);
4201
4202         saved = c->index;
4203         c->index = c->saved_index;
4204         r = container_next_item(m, c, &m->rindex);
4205         c->index = saved;
4206         if (r < 0)
4207                 return r;
4208
4209         return 1;
4210 }
4211
4212 static void message_quit_container(sd_bus_message *m) {
4213         struct bus_container *c;
4214
4215         assert(m);
4216         assert(m->sealed);
4217         assert(m->n_containers > 0);
4218
4219         c = message_get_container(m);
4220
4221         /* Undo seeks */
4222         assert(m->rindex >= c->before);
4223         m->rindex = c->before;
4224
4225         /* Free container */
4226         free(c->signature);
4227         free(c->offsets);
4228         m->n_containers--;
4229
4230         /* Correct index of new top-level container */
4231         c = message_get_container(m);
4232         c->index = c->saved_index;
4233 }
4234
4235 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4236         struct bus_container *c;
4237         int r;
4238
4239         assert_return(m, -EINVAL);
4240         assert_return(m->sealed, -EPERM);
4241
4242         if (message_end_of_signature(m))
4243                 goto eof;
4244
4245         if (message_end_of_array(m, m->rindex))
4246                 goto eof;
4247
4248         c = message_get_container(m);
4249
4250         if (bus_type_is_basic(c->signature[c->index])) {
4251                 if (contents)
4252                         *contents = NULL;
4253                 if (type)
4254                         *type = c->signature[c->index];
4255                 return 1;
4256         }
4257
4258         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4259
4260                 if (contents) {
4261                         size_t l;
4262                         char *sig;
4263
4264                         r = signature_element_length(c->signature+c->index+1, &l);
4265                         if (r < 0)
4266                                 return r;
4267
4268                         assert(l >= 1);
4269
4270                         sig = strndup(c->signature + c->index + 1, l);
4271                         if (!sig)
4272                                 return -ENOMEM;
4273
4274                         free(c->peeked_signature);
4275                         *contents = c->peeked_signature = sig;
4276                 }
4277
4278                 if (type)
4279                         *type = SD_BUS_TYPE_ARRAY;
4280
4281                 return 1;
4282         }
4283
4284         if (IN_SET(c->signature[c->index], SD_BUS_TYPE_STRUCT_BEGIN, SD_BUS_TYPE_DICT_ENTRY_BEGIN)) {
4285
4286                 if (contents) {
4287                         size_t l;
4288                         char *sig;
4289
4290                         r = signature_element_length(c->signature+c->index, &l);
4291                         if (r < 0)
4292                                 return r;
4293
4294                         assert(l >= 2);
4295                         sig = strndup(c->signature + c->index + 1, l - 2);
4296                         if (!sig)
4297                                 return -ENOMEM;
4298
4299                         free(c->peeked_signature);
4300                         *contents = c->peeked_signature = sig;
4301                 }
4302
4303                 if (type)
4304                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4305
4306                 return 1;
4307         }
4308
4309         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4310                 if (contents) {
4311                         void *q;
4312
4313                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4314                                 size_t k;
4315
4316                                 if (c->item_size < 2)
4317                                         return -EBADMSG;
4318
4319                                 /* Look for the NUL delimiter that
4320                                    separates the payload from the
4321                                    signature. Since the body might be
4322                                    in a different part that then the
4323                                    signature we map byte by byte. */
4324
4325                                 for (k = 2; k <= c->item_size; k++) {
4326                                         size_t where;
4327
4328                                         where = m->rindex + c->item_size - k;
4329                                         r = message_peek_body(m, &where, 1, k, &q);
4330                                         if (r < 0)
4331                                                 return r;
4332
4333                                         if (*(char*) q == 0)
4334                                                 break;
4335                                 }
4336
4337                                 if (k > c->item_size)
4338                                         return -EBADMSG;
4339
4340                                 free(c->peeked_signature);
4341                                 c->peeked_signature = strndup((char*) q + 1, k - 1);
4342                                 if (!c->peeked_signature)
4343                                         return -ENOMEM;
4344
4345                                 if (!signature_is_valid(c->peeked_signature, true))
4346                                         return -EBADMSG;
4347
4348                                 *contents = c->peeked_signature;
4349                         } else {
4350                                 size_t rindex, l;
4351
4352                                 rindex = m->rindex;
4353                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4354                                 if (r < 0)
4355                                         return r;
4356
4357                                 l = *(uint8_t*) q;
4358                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4359                                 if (r < 0)
4360                                         return r;
4361
4362                                 if (!validate_signature(q, l))
4363                                         return -EBADMSG;
4364
4365                                 *contents = q;
4366                         }
4367                 }
4368
4369                 if (type)
4370                         *type = SD_BUS_TYPE_VARIANT;
4371
4372                 return 1;
4373         }
4374
4375         return -EINVAL;
4376
4377 eof:
4378         if (type)
4379                 *type = 0;
4380         if (contents)
4381                 *contents = NULL;
4382         return 0;
4383 }
4384
4385 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4386         struct bus_container *c;
4387
4388         assert_return(m, -EINVAL);
4389         assert_return(m->sealed, -EPERM);
4390
4391         if (complete) {
4392                 message_reset_containers(m);
4393                 m->rindex = 0;
4394
4395                 c = message_get_container(m);
4396         } else {
4397                 c = message_get_container(m);
4398
4399                 c->offset_index = 0;
4400                 c->index = 0;
4401                 m->rindex = c->begin;
4402         }
4403
4404         c->offset_index = 0;
4405         c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4406
4407         return !isempty(c->signature);
4408 }
4409
4410 static int message_read_ap(
4411                 sd_bus_message *m,
4412                 const char *types,
4413                 va_list ap) {
4414
4415         unsigned n_array, n_struct;
4416         TypeStack stack[BUS_CONTAINER_DEPTH];
4417         unsigned stack_ptr = 0;
4418         unsigned n_loop = 0;
4419         int r;
4420
4421         assert(m);
4422
4423         if (isempty(types))
4424                 return 0;
4425
4426         /* Ideally, we'd just call ourselves recursively on every
4427          * complex type. However, the state of a va_list that is
4428          * passed to a function is undefined after that function
4429          * returns. This means we need to docode the va_list linearly
4430          * in a single stackframe. We hence implement our own
4431          * home-grown stack in an array. */
4432
4433         n_array = (unsigned) -1; /* length of current array entries */
4434         n_struct = strlen(types); /* length of current struct contents signature */
4435
4436         for (;;) {
4437                 const char *t;
4438
4439                 n_loop++;
4440
4441                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4442                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4443                         if (r < 0)
4444                                 return r;
4445                         if (r == 0)
4446                                 break;
4447
4448                         r = sd_bus_message_exit_container(m);
4449                         if (r < 0)
4450                                 return r;
4451
4452                         continue;
4453                 }
4454
4455                 t = types;
4456                 if (n_array != (unsigned) -1)
4457                         n_array--;
4458                 else {
4459                         types++;
4460                         n_struct--;
4461                 }
4462
4463                 switch (*t) {
4464
4465                 case SD_BUS_TYPE_BYTE:
4466                 case SD_BUS_TYPE_BOOLEAN:
4467                 case SD_BUS_TYPE_INT16:
4468                 case SD_BUS_TYPE_UINT16:
4469                 case SD_BUS_TYPE_INT32:
4470                 case SD_BUS_TYPE_UINT32:
4471                 case SD_BUS_TYPE_INT64:
4472                 case SD_BUS_TYPE_UINT64:
4473                 case SD_BUS_TYPE_DOUBLE:
4474                 case SD_BUS_TYPE_STRING:
4475                 case SD_BUS_TYPE_OBJECT_PATH:
4476                 case SD_BUS_TYPE_SIGNATURE:
4477                 case SD_BUS_TYPE_UNIX_FD: {
4478                         void *p;
4479
4480                         p = va_arg(ap, void*);
4481                         r = sd_bus_message_read_basic(m, *t, p);
4482                         if (r < 0)
4483                                 return r;
4484                         if (r == 0) {
4485                                 if (n_loop <= 1)
4486                                         return 0;
4487
4488                                 return -ENXIO;
4489                         }
4490
4491                         break;
4492                 }
4493
4494                 case SD_BUS_TYPE_ARRAY: {
4495                         size_t k;
4496
4497                         r = signature_element_length(t + 1, &k);
4498                         if (r < 0)
4499                                 return r;
4500
4501                         {
4502                                 char s[k + 1];
4503                                 memcpy(s, t + 1, k);
4504                                 s[k] = 0;
4505
4506                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4507                                 if (r < 0)
4508                                         return r;
4509                                 if (r == 0) {
4510                                         if (n_loop <= 1)
4511                                                 return 0;
4512
4513                                         return -ENXIO;
4514                                 }
4515                         }
4516
4517                         if (n_array == (unsigned) -1) {
4518                                 types += k;
4519                                 n_struct -= k;
4520                         }
4521
4522                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4523                         if (r < 0)
4524                                 return r;
4525
4526                         types = t + 1;
4527                         n_struct = k;
4528                         n_array = va_arg(ap, unsigned);
4529
4530                         break;
4531                 }
4532
4533                 case SD_BUS_TYPE_VARIANT: {
4534                         const char *s;
4535
4536                         s = va_arg(ap, const char *);
4537                         if (!s)
4538                                 return -EINVAL;
4539
4540                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4541                         if (r < 0)
4542                                 return r;
4543                         if (r == 0) {
4544                                 if (n_loop <= 1)
4545                                         return 0;
4546
4547                                 return -ENXIO;
4548                         }
4549
4550                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4551                         if (r < 0)
4552                                 return r;
4553
4554                         types = s;
4555                         n_struct = strlen(s);
4556                         n_array = (unsigned) -1;
4557
4558                         break;
4559                 }
4560
4561                 case SD_BUS_TYPE_STRUCT_BEGIN:
4562                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4563                         size_t k;
4564
4565                         r = signature_element_length(t, &k);
4566                         if (r < 0)
4567                                 return r;
4568
4569                         {
4570                                 char s[k - 1];
4571                                 memcpy(s, t + 1, k - 2);
4572                                 s[k - 2] = 0;
4573
4574                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4575                                 if (r < 0)
4576                                         return r;
4577                                 if (r == 0) {
4578                                         if (n_loop <= 1)
4579                                                 return 0;
4580                                         return -ENXIO;
4581                                 }
4582                         }
4583
4584                         if (n_array == (unsigned) -1) {
4585                                 types += k - 1;
4586                                 n_struct -= k - 1;
4587                         }
4588
4589                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4590                         if (r < 0)
4591                                 return r;
4592
4593                         types = t + 1;
4594                         n_struct = k - 2;
4595                         n_array = (unsigned) -1;
4596
4597                         break;
4598                 }
4599
4600                 default:
4601                         return -EINVAL;
4602                 }
4603         }
4604
4605         return 1;
4606 }
4607
4608 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4609         va_list ap;
4610         int r;
4611
4612         assert_return(m, -EINVAL);
4613         assert_return(m->sealed, -EPERM);
4614         assert_return(types, -EINVAL);
4615
4616         va_start(ap, types);
4617         r = message_read_ap(m, types, ap);
4618         va_end(ap);
4619
4620         return r;
4621 }
4622
4623 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4624         int r;
4625
4626         assert_return(m, -EINVAL);
4627         assert_return(m->sealed, -EPERM);
4628
4629         /* If types is NULL, read exactly one element */
4630         if (!types) {
4631                 struct bus_container *c;
4632                 size_t l;
4633
4634                 if (message_end_of_signature(m))
4635                         return -ENXIO;
4636
4637                 if (message_end_of_array(m, m->rindex))
4638                         return 0;
4639
4640                 c = message_get_container(m);
4641
4642                 r = signature_element_length(c->signature + c->index, &l);
4643                 if (r < 0)
4644                         return r;
4645
4646                 types = strndupa(c->signature + c->index, l);
4647         }
4648
4649         switch (*types) {
4650
4651         case 0: /* Nothing to drop */
4652                 return 0;
4653
4654         case SD_BUS_TYPE_BYTE:
4655         case SD_BUS_TYPE_BOOLEAN:
4656         case SD_BUS_TYPE_INT16:
4657         case SD_BUS_TYPE_UINT16:
4658         case SD_BUS_TYPE_INT32:
4659         case SD_BUS_TYPE_UINT32:
4660         case SD_BUS_TYPE_INT64:
4661         case SD_BUS_TYPE_UINT64:
4662         case SD_BUS_TYPE_DOUBLE:
4663         case SD_BUS_TYPE_STRING:
4664         case SD_BUS_TYPE_OBJECT_PATH:
4665         case SD_BUS_TYPE_SIGNATURE:
4666         case SD_BUS_TYPE_UNIX_FD:
4667
4668                 r = sd_bus_message_read_basic(m, *types, NULL);
4669                 if (r <= 0)
4670                         return r;
4671
4672                 r = sd_bus_message_skip(m, types + 1);
4673                 if (r < 0)
4674                         return r;
4675
4676                 return 1;
4677
4678         case SD_BUS_TYPE_ARRAY: {
4679                 size_t k;
4680
4681                 r = signature_element_length(types + 1, &k);
4682                 if (r < 0)
4683                         return r;
4684
4685                 {
4686                         char s[k+1];
4687                         memcpy(s, types+1, k);
4688                         s[k] = 0;
4689
4690                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4691                         if (r <= 0)
4692                                 return r;
4693
4694                         for (;;) {
4695                                 r = sd_bus_message_skip(m, s);
4696                                 if (r < 0)
4697                                         return r;
4698                                 if (r == 0)
4699                                         break;
4700                         }
4701
4702                         r = sd_bus_message_exit_container(m);
4703                         if (r < 0)
4704                                 return r;
4705                 }
4706
4707                 r = sd_bus_message_skip(m, types + 1 + k);
4708                 if (r < 0)
4709                         return r;
4710
4711                 return 1;
4712         }
4713
4714         case SD_BUS_TYPE_VARIANT: {
4715                 const char *contents;
4716                 char x;
4717
4718                 r = sd_bus_message_peek_type(m, &x, &contents);
4719                 if (r <= 0)
4720                         return r;
4721
4722                 if (x != SD_BUS_TYPE_VARIANT)
4723                         return -ENXIO;
4724
4725                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4726                 if (r <= 0)
4727                         return r;
4728
4729                 r = sd_bus_message_skip(m, contents);
4730                 if (r < 0)
4731                         return r;
4732                 assert(r != 0);
4733
4734                 r = sd_bus_message_exit_container(m);
4735                 if (r < 0)
4736                         return r;
4737
4738                 r = sd_bus_message_skip(m, types + 1);
4739                 if (r < 0)
4740                         return r;
4741
4742                 return 1;
4743         }
4744
4745         case SD_BUS_TYPE_STRUCT_BEGIN:
4746         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4747                 size_t k;
4748
4749                 r = signature_element_length(types, &k);
4750                 if (r < 0)
4751                         return r;
4752
4753                 {
4754                         char s[k-1];
4755                         memcpy(s, types+1, k-2);
4756                         s[k-2] = 0;
4757
4758                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4759                         if (r <= 0)
4760                                 return r;
4761
4762                         r = sd_bus_message_skip(m, s);
4763                         if (r < 0)
4764                                 return r;
4765
4766                         r = sd_bus_message_exit_container(m);
4767                         if (r < 0)
4768                                 return r;
4769                 }
4770
4771                 r = sd_bus_message_skip(m, types + k);
4772                 if (r < 0)
4773                         return r;
4774
4775                 return 1;
4776         }
4777
4778         default:
4779                 return -EINVAL;
4780         }
4781 }
4782
4783 _public_ int sd_bus_message_read_array(
4784                 sd_bus_message *m,
4785                 char type,
4786                 const void **ptr,
4787                 size_t *size) {
4788
4789         struct bus_container *c;
4790         void *p;
4791         size_t sz;
4792         ssize_t align;
4793         int r;
4794
4795         assert_return(m, -EINVAL);
4796         assert_return(m->sealed, -EPERM);
4797         assert_return(bus_type_is_trivial(type), -EINVAL);
4798         assert_return(ptr, -EINVAL);
4799         assert_return(size, -EINVAL);
4800         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -EOPNOTSUPP);
4801
4802         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4803         if (r <= 0)
4804                 return r;
4805
4806         c = message_get_container(m);
4807
4808         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4809                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4810                 if (align < 0)
4811                         return align;
4812
4813                 sz = c->end - c->begin;
4814         } else {
4815                 align = bus_type_get_alignment(type);
4816                 if (align < 0)
4817                         return align;
4818
4819                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4820         }
4821
4822         if (sz == 0)
4823                 /* Zero length array, let's return some aligned
4824                  * pointer that is not NULL */
4825                 p = (uint8_t*) NULL + align;
4826         else {
4827                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4828                 if (r < 0)
4829                         goto fail;
4830         }
4831
4832         r = sd_bus_message_exit_container(m);
4833         if (r < 0)
4834                 goto fail;
4835
4836         *ptr = (const void*) p;
4837         *size = sz;
4838
4839         return 1;
4840
4841 fail:
4842         message_quit_container(m);
4843         return r;
4844 }
4845
4846 static int message_peek_fields(
4847                 sd_bus_message *m,
4848                 size_t *rindex,
4849                 size_t align,
4850                 size_t nbytes,
4851                 void **ret) {
4852
4853         assert(m);
4854         assert(rindex);
4855         assert(align > 0);
4856
4857         return buffer_peek(BUS_MESSAGE_FIELDS(m), m->fields_size, rindex, align, nbytes, ret);
4858 }
4859
4860 static int message_peek_field_uint32(
4861                 sd_bus_message *m,
4862                 size_t *ri,
4863                 size_t item_size,
4864                 uint32_t *ret) {
4865
4866         int r;
4867         void *q;
4868
4869         assert(m);
4870         assert(ri);
4871
4872         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4873                 return -EBADMSG;
4874
4875         /* identical for gvariant and dbus1 */
4876
4877         r = message_peek_fields(m, ri, 4, 4, &q);
4878         if (r < 0)
4879                 return r;
4880
4881         if (ret)
4882                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4883
4884         return 0;
4885 }
4886
4887 static int message_peek_field_uint64(
4888                 sd_bus_message *m,
4889                 size_t *ri,
4890                 size_t item_size,
4891                 uint64_t *ret) {
4892
4893         int r;
4894         void *q;
4895
4896         assert(m);
4897         assert(ri);
4898
4899         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 8)
4900                 return -EBADMSG;
4901
4902         /* identical for gvariant and dbus1 */
4903
4904         r = message_peek_fields(m, ri, 8, 8, &q);
4905         if (r < 0)
4906                 return r;
4907
4908         if (ret)
4909                 *ret = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
4910
4911         return 0;
4912 }
4913
4914 static int message_peek_field_string(
4915                 sd_bus_message *m,
4916                 bool (*validate)(const char *p),
4917                 size_t *ri,
4918                 size_t item_size,
4919                 const char **ret) {
4920
4921         uint32_t l;
4922         int r;
4923         void *q;
4924
4925         assert(m);
4926         assert(ri);
4927
4928         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4929
4930                 if (item_size <= 0)
4931                         return -EBADMSG;
4932
4933                 r = message_peek_fields(m, ri, 1, item_size, &q);
4934                 if (r < 0)
4935                         return r;
4936
4937                 l = item_size - 1;
4938         } else {
4939                 r = message_peek_field_uint32(m, ri, 4, &l);
4940                 if (r < 0)
4941                         return r;
4942
4943                 r = message_peek_fields(m, ri, 1, l+1, &q);
4944                 if (r < 0)
4945                         return r;
4946         }
4947
4948         if (validate) {
4949                 if (!validate_nul(q, l))
4950                         return -EBADMSG;
4951
4952                 if (!validate(q))
4953                         return -EBADMSG;
4954         } else {
4955                 if (!validate_string(q, l))
4956                         return -EBADMSG;
4957         }
4958
4959         if (ret)
4960                 *ret = q;
4961
4962         return 0;
4963 }
4964
4965 static int message_peek_field_signature(
4966                 sd_bus_message *m,
4967                 size_t *ri,
4968                 size_t item_size,
4969                 const char **ret) {
4970
4971         size_t l;
4972         int r;
4973         void *q;
4974
4975         assert(m);
4976         assert(ri);
4977
4978         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4979
4980                 if (item_size <= 0)
4981                         return -EBADMSG;
4982
4983                 r = message_peek_fields(m, ri, 1, item_size, &q);
4984                 if (r < 0)
4985                         return r;
4986
4987                 l = item_size - 1;
4988         } else {
4989                 r = message_peek_fields(m, ri, 1, 1, &q);
4990                 if (r < 0)
4991                         return r;
4992
4993                 l = *(uint8_t*) q;
4994                 r = message_peek_fields(m, ri, 1, l+1, &q);
4995                 if (r < 0)
4996                         return r;
4997         }
4998
4999         if (!validate_signature(q, l))
5000                 return -EBADMSG;
5001
5002         if (ret)
5003                 *ret = q;
5004
5005         return 0;
5006 }
5007
5008 static int message_skip_fields(
5009                 sd_bus_message *m,
5010                 size_t *ri,
5011                 uint32_t array_size,
5012                 const char **signature) {
5013
5014         size_t original_index;
5015         int r;
5016
5017         assert(m);
5018         assert(ri);
5019         assert(signature);
5020         assert(!BUS_MESSAGE_IS_GVARIANT(m));
5021
5022         original_index = *ri;
5023
5024         for (;;) {
5025                 char t;
5026                 size_t l;
5027
5028                 if (array_size != (uint32_t) -1 &&
5029                     array_size <= *ri - original_index)
5030                         return 0;
5031
5032                 t = **signature;
5033                 if (!t)
5034                         return 0;
5035
5036                 if (t == SD_BUS_TYPE_STRING) {
5037
5038                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
5039                         if (r < 0)
5040                                 return r;
5041
5042                         (*signature)++;
5043
5044                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
5045
5046                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
5047                         if (r < 0)
5048                                 return r;
5049
5050                         (*signature)++;
5051
5052                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
5053
5054                         r = message_peek_field_signature(m, ri, 0, NULL);
5055                         if (r < 0)
5056                                 return r;
5057
5058                         (*signature)++;
5059
5060                 } else if (bus_type_is_basic(t)) {
5061                         ssize_t align, k;
5062
5063                         align = bus_type_get_alignment(t);
5064                         k = bus_type_get_size(t);
5065                         assert(align > 0 && k > 0);
5066
5067                         r = message_peek_fields(m, ri, align, k, NULL);
5068                         if (r < 0)
5069                                 return r;
5070
5071                         (*signature)++;
5072
5073                 } else if (t == SD_BUS_TYPE_ARRAY) {
5074
5075                         r = signature_element_length(*signature+1, &l);
5076                         if (r < 0)
5077                                 return r;
5078
5079                         assert(l >= 1);
5080                         {
5081                                 char sig[l-1], *s;
5082                                 uint32_t nas;
5083                                 int alignment;
5084
5085                                 strncpy(sig, *signature + 1, l-1);
5086                                 s = sig;
5087
5088                                 alignment = bus_type_get_alignment(sig[0]);
5089                                 if (alignment < 0)
5090                                         return alignment;
5091
5092                                 r = message_peek_field_uint32(m, ri, 0, &nas);
5093                                 if (r < 0)
5094                                         return r;
5095                                 if (nas > BUS_ARRAY_MAX_SIZE)
5096                                         return -EBADMSG;
5097
5098                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
5099                                 if (r < 0)
5100                                         return r;
5101
5102                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
5103                                 if (r < 0)
5104                                         return r;
5105                         }
5106
5107                         (*signature) += 1 + l;
5108
5109                 } else if (t == SD_BUS_TYPE_VARIANT) {
5110                         const char *s;
5111
5112                         r = message_peek_field_signature(m, ri, 0, &s);
5113                         if (r < 0)
5114                                 return r;
5115
5116                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5117                         if (r < 0)
5118                                 return r;
5119
5120                         (*signature)++;
5121
5122                 } else if (IN_SET(t, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY)) {
5123
5124                         r = signature_element_length(*signature, &l);
5125                         if (r < 0)
5126                                 return r;
5127
5128                         assert(l >= 2);
5129                         {
5130                                 char sig[l-1], *s;
5131                                 strncpy(sig, *signature + 1, l-1);
5132                                 s = sig;
5133
5134                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5135                                 if (r < 0)
5136                                         return r;
5137                         }
5138
5139                         *signature += l;
5140                 } else
5141                         return -EINVAL;
5142         }
5143 }
5144
5145 int bus_message_parse_fields(sd_bus_message *m) {
5146         size_t ri;
5147         int r;
5148         uint32_t unix_fds = 0;
5149         bool unix_fds_set = false;
5150         void *offsets = NULL;
5151         unsigned n_offsets = 0;
5152         size_t sz = 0;
5153         unsigned i = 0;
5154
5155         assert(m);
5156
5157         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5158                 char *p;
5159
5160                 /* Read the signature from the end of the body variant first */
5161                 sz = bus_gvariant_determine_word_size(BUS_MESSAGE_SIZE(m), 0);
5162                 if (m->footer_accessible < 1 + sz)
5163                         return -EBADMSG;
5164
5165                 p = (char*) m->footer + m->footer_accessible - (1 + sz);
5166                 for (;;) {
5167                         if (p < (char*) m->footer)
5168                                 return -EBADMSG;
5169
5170                         if (*p == 0) {
5171                                 size_t l;
5172                                 char *c;
5173
5174                                 /* We found the beginning of the signature
5175                                  * string, yay! We require the body to be a
5176                                  * structure, so verify it and then strip the
5177                                  * opening/closing brackets. */
5178
5179                                 l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
5180                                 if (l < 2 ||
5181                                     p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
5182                                     p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
5183                                         return -EBADMSG;
5184
5185                                 c = strndup(p + 1 + 1, l - 2);
5186                                 if (!c)
5187                                         return -ENOMEM;
5188
5189                                 free(m->root_container.signature);
5190                                 m->root_container.signature = c;
5191                                 break;
5192                         }
5193
5194                         p--;
5195                 }
5196
5197                 /* Calculate the actual user body size, by removing
5198                  * the trailing variant signature and struct offset
5199                  * table */
5200                 m->user_body_size = m->body_size - ((char*) m->footer + m->footer_accessible - p);
5201
5202                 /* Pull out the offset table for the fields array */
5203                 sz = bus_gvariant_determine_word_size(m->fields_size, 0);
5204                 if (sz > 0) {
5205                         size_t framing;
5206                         void *q;
5207
5208                         ri = m->fields_size - sz;
5209                         r = message_peek_fields(m, &ri, 1, sz, &q);
5210                         if (r < 0)
5211                                 return r;
5212
5213                         framing = bus_gvariant_read_word_le(q, sz);
5214                         if (framing >= m->fields_size - sz)
5215                                 return -EBADMSG;
5216                         if ((m->fields_size - framing) % sz != 0)
5217                                 return -EBADMSG;
5218
5219                         ri = framing;
5220                         r = message_peek_fields(m, &ri, 1, m->fields_size - framing, &offsets);
5221                         if (r < 0)
5222                                 return r;
5223
5224                         n_offsets = (m->fields_size - framing) / sz;
5225                 }
5226         } else
5227                 m->user_body_size = m->body_size;
5228
5229         ri = 0;
5230         while (ri < m->fields_size) {
5231                 _cleanup_free_ char *sig = NULL;
5232                 const char *signature;
5233                 uint64_t field_type;
5234                 size_t item_size = (size_t) -1;
5235
5236                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5237                         uint64_t *u64;
5238
5239                         if (i >= n_offsets)
5240                                 break;
5241
5242                         if (i == 0)
5243                                 ri = 0;
5244                         else
5245                                 ri = ALIGN_TO(bus_gvariant_read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
5246
5247                         r = message_peek_fields(m, &ri, 8, 8, (void**) &u64);
5248                         if (r < 0)
5249                                 return r;
5250
5251                         field_type = BUS_MESSAGE_BSWAP64(m, *u64);
5252                 } else {
5253                         uint8_t *u8;
5254
5255                         r = message_peek_fields(m, &ri, 8, 1, (void**) &u8);
5256                         if (r < 0)
5257                                 return r;
5258
5259                         field_type = *u8;
5260                 }
5261
5262                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5263                         size_t where, end;
5264                         char *b;
5265                         void *q;
5266
5267                         end = bus_gvariant_read_word_le((uint8_t*) offsets + i*sz, sz);
5268
5269                         if (end < ri)
5270                                 return -EBADMSG;
5271
5272                         where = ri = ALIGN_TO(ri, 8);
5273                         item_size = end - ri;
5274                         r = message_peek_fields(m, &where, 1, item_size, &q);
5275                         if (r < 0)
5276                                 return r;
5277
5278                         b = memrchr(q, 0, item_size);
5279                         if (!b)
5280                                 return -EBADMSG;
5281
5282                         sig = strndup(b+1, item_size - (b+1-(char*) q));
5283                         if (!sig)
5284                                 return -ENOMEM;
5285
5286                         signature = sig;
5287                         item_size = b - (char*) q;
5288                 } else {
5289                         r = message_peek_field_signature(m, &ri, 0, &signature);
5290                         if (r < 0)
5291                                 return r;
5292                 }
5293
5294                 switch (field_type) {
5295
5296                 case _BUS_MESSAGE_HEADER_INVALID:
5297                         return -EBADMSG;
5298
5299                 case BUS_MESSAGE_HEADER_PATH:
5300
5301                         if (m->path)
5302                                 return -EBADMSG;
5303
5304                         if (!streq(signature, "o"))
5305                                 return -EBADMSG;
5306
5307                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5308                         break;
5309
5310                 case BUS_MESSAGE_HEADER_INTERFACE:
5311
5312                         if (m->interface)
5313                                 return -EBADMSG;
5314
5315                         if (!streq(signature, "s"))
5316                                 return -EBADMSG;
5317
5318                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5319                         break;
5320
5321                 case BUS_MESSAGE_HEADER_MEMBER:
5322
5323                         if (m->member)
5324                                 return -EBADMSG;
5325
5326                         if (!streq(signature, "s"))
5327                                 return -EBADMSG;
5328
5329                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5330                         break;
5331
5332                 case BUS_MESSAGE_HEADER_ERROR_NAME:
5333
5334                         if (m->error.name)
5335                                 return -EBADMSG;
5336
5337                         if (!streq(signature, "s"))
5338                                 return -EBADMSG;
5339
5340                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5341                         if (r >= 0)
5342                                 m->error._need_free = -1;
5343
5344                         break;
5345
5346                 case BUS_MESSAGE_HEADER_DESTINATION:
5347
5348                         if (m->destination)
5349                                 return -EBADMSG;
5350
5351                         if (!streq(signature, "s"))
5352                                 return -EBADMSG;
5353
5354                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5355                         break;
5356
5357                 case BUS_MESSAGE_HEADER_SENDER:
5358
5359                         if (m->sender)
5360                                 return -EBADMSG;
5361
5362                         if (!streq(signature, "s"))
5363                                 return -EBADMSG;
5364
5365                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5366
5367                         if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5368                                 m->creds.unique_name = (char*) m->sender;
5369                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5370                         }
5371
5372                         break;
5373
5374
5375                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5376                         const char *s;
5377                         char *c;
5378
5379                         if (BUS_MESSAGE_IS_GVARIANT(m)) /* only applies to dbus1 */
5380                                 return -EBADMSG;
5381
5382                         if (m->root_container.signature)
5383                                 return -EBADMSG;
5384
5385                         if (!streq(signature, "g"))
5386                                 return -EBADMSG;
5387
5388                         r = message_peek_field_signature(m, &ri, item_size, &s);
5389                         if (r < 0)
5390                                 return r;
5391
5392                         c = strdup(s);
5393                         if (!c)
5394                                 return -ENOMEM;
5395
5396                         free(m->root_container.signature);
5397                         m->root_container.signature = c;
5398                         break;
5399                 }
5400
5401                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5402
5403                         if (m->reply_cookie != 0)
5404                                 return -EBADMSG;
5405
5406                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5407                                 /* 64bit on dbus2 */
5408
5409                                 if (!streq(signature, "t"))
5410                                         return -EBADMSG;
5411
5412                                 r = message_peek_field_uint64(m, &ri, item_size, &m->reply_cookie);
5413                                 if (r < 0)
5414                                         return r;
5415                         } else {
5416                                 /* 32bit on dbus1 */
5417                                 uint32_t serial;
5418
5419                                 if (!streq(signature, "u"))
5420                                         return -EBADMSG;
5421
5422                                 r = message_peek_field_uint32(m, &ri, item_size, &serial);
5423                                 if (r < 0)
5424                                         return r;
5425
5426                                 m->reply_cookie = serial;
5427                         }
5428
5429                         if (m->reply_cookie == 0)
5430                                 return -EBADMSG;
5431
5432                         break;
5433
5434                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5435                         if (unix_fds_set)
5436                                 return -EBADMSG;
5437
5438                         if (!streq(signature, "u"))
5439                                 return -EBADMSG;
5440
5441                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5442                         if (r < 0)
5443                                 return -EBADMSG;
5444
5445                         unix_fds_set = true;
5446                         break;
5447
5448                 default:
5449                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5450                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5451                 }
5452
5453                 if (r < 0)
5454                         return r;
5455
5456                 i++;
5457         }
5458
5459         if (m->n_fds != unix_fds)
5460                 return -EBADMSG;
5461
5462         switch (m->header->type) {
5463
5464         case SD_BUS_MESSAGE_SIGNAL:
5465                 if (!m->path || !m->interface || !m->member)
5466                         return -EBADMSG;
5467
5468                 if (m->reply_cookie != 0)
5469                         return -EBADMSG;
5470
5471                 break;
5472
5473         case SD_BUS_MESSAGE_METHOD_CALL:
5474
5475                 if (!m->path || !m->member)
5476                         return -EBADMSG;
5477
5478                 if (m->reply_cookie != 0)
5479                         return -EBADMSG;
5480
5481                 break;
5482
5483         case SD_BUS_MESSAGE_METHOD_RETURN:
5484
5485                 if (m->reply_cookie == 0)
5486                         return -EBADMSG;
5487                 break;
5488
5489         case SD_BUS_MESSAGE_METHOD_ERROR:
5490
5491                 if (m->reply_cookie == 0 || !m->error.name)
5492                         return -EBADMSG;
5493                 break;
5494         }
5495
5496         /* Refuse non-local messages that claim they are local */
5497         if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5498                 return -EBADMSG;
5499         if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5500                 return -EBADMSG;
5501         if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5502                 return -EBADMSG;
5503
5504         m->root_container.end = m->user_body_size;
5505
5506         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5507                 r = build_struct_offsets(
5508                                 m,
5509                                 m->root_container.signature,
5510                                 m->user_body_size,
5511                                 &m->root_container.item_size,
5512                                 &m->root_container.offsets,
5513                                 &m->root_container.n_offsets);
5514                 if (r < 0)
5515                         return r;
5516         }
5517
5518         /* Try to read the error message, but if we can't it's a non-issue */
5519         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5520                 (void) sd_bus_message_read(m, "s", &m->error.message);
5521
5522         return 0;
5523 }
5524
5525 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5526         assert_return(m, -EINVAL);
5527         assert_return(destination, -EINVAL);
5528         assert_return(!m->sealed, -EPERM);
5529         assert_return(!m->destination, -EEXIST);
5530
5531         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5532 }
5533
5534 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5535         size_t total;
5536         void *p, *e;
5537         unsigned i;
5538         struct bus_body_part *part;
5539
5540         assert(m);
5541         assert(buffer);
5542         assert(sz);
5543
5544         total = BUS_MESSAGE_SIZE(m);
5545
5546         p = malloc(total);
5547         if (!p)
5548                 return -ENOMEM;
5549
5550         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5551         MESSAGE_FOREACH_PART(part, i, m)
5552                 e = mempcpy(e, part->data, part->size);
5553
5554         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5555
5556         *buffer = p;
5557         *sz = total;
5558
5559         return 0;
5560 }
5561
5562 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5563         const char *s;
5564         int r;
5565
5566         assert(m);
5567         assert(l);
5568
5569         r = sd_bus_message_enter_container(m, 'a', "s");
5570         if (r <= 0)
5571                 return r;
5572
5573         while ((r = sd_bus_message_read_basic(m, 's', &s)) > 0) {
5574                 r = strv_extend(l, s);
5575                 if (r < 0)
5576                         return r;
5577         }
5578         if (r < 0)
5579                 return r;
5580
5581         r = sd_bus_message_exit_container(m);
5582         if (r < 0)
5583                 return r;
5584
5585         return 1;
5586 }
5587
5588 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5589         char **strv = NULL;
5590         int r;
5591
5592         assert_return(m, -EINVAL);
5593         assert_return(m->sealed, -EPERM);
5594         assert_return(l, -EINVAL);
5595
5596         r = bus_message_read_strv_extend(m, &strv);
5597         if (r <= 0) {
5598                 strv_free(strv);
5599                 return r;
5600         }
5601
5602         *l = strv;
5603         return 1;
5604 }
5605
5606 static int bus_message_get_arg_skip(
5607                 sd_bus_message *m,
5608                 unsigned i,
5609                 char *_type,
5610                 const char **_contents) {
5611
5612         unsigned j;
5613         int r;
5614
5615         r = sd_bus_message_rewind(m, true);
5616         if (r < 0)
5617                 return r;
5618
5619         for (j = 0;; j++) {
5620                 const char *contents;
5621                 char type;
5622
5623                 r = sd_bus_message_peek_type(m, &type, &contents);
5624                 if (r < 0)
5625                         return r;
5626                 if (r == 0)
5627                         return -ENXIO;
5628
5629                 /* Don't match against arguments after the first one we don't understand */
5630                 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE) &&
5631                     !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
5632                         return -ENXIO;
5633
5634                 if (j >= i) {
5635                         if (_contents)
5636                                 *_contents = contents;
5637                         if (_type)
5638                                 *_type = type;
5639                         return 0;
5640                 }
5641
5642                 r = sd_bus_message_skip(m, NULL);
5643                 if (r < 0)
5644                         return r;
5645         }
5646
5647 }
5648
5649 int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str) {
5650         char type;
5651         int r;
5652
5653         assert(m);
5654         assert(str);
5655
5656         r = bus_message_get_arg_skip(m, i, &type, NULL);
5657         if (r < 0)
5658                 return r;
5659
5660         if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE))
5661                 return -ENXIO;
5662
5663         return sd_bus_message_read_basic(m, type, str);
5664 }
5665
5666 int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv) {
5667         const char *contents;
5668         char type;
5669         int r;
5670
5671         assert(m);
5672         assert(strv);
5673
5674         r = bus_message_get_arg_skip(m, i, &type, &contents);
5675         if (r < 0)
5676                 return r;
5677
5678         if (type != SD_BUS_TYPE_ARRAY)
5679                 return -ENXIO;
5680         if (!STR_IN_SET(contents, "s", "o", "g"))
5681                 return -ENXIO;
5682
5683         return sd_bus_message_read_strv(m, strv);
5684 }
5685
5686 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5687         assert_return(m, EINVAL);
5688
5689         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5690                 return 0;
5691
5692         return sd_bus_error_get_errno(&m->error);
5693 }
5694
5695 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5696         struct bus_container *c;
5697
5698         assert_return(m, NULL);
5699
5700         c = complete ? &m->root_container : message_get_container(m);
5701         return strempty(c->signature);
5702 }
5703
5704 _public_ int sd_bus_message_is_empty(sd_bus_message *m) {
5705         assert_return(m, -EINVAL);
5706
5707         return isempty(m->root_container.signature);
5708 }
5709
5710 _public_ int sd_bus_message_has_signature(sd_bus_message *m, const char *signature) {
5711         assert_return(m, -EINVAL);
5712
5713         return streq(strempty(m->root_container.signature), strempty(signature));
5714 }
5715
5716 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5717         bool done_something = false;
5718         int r;
5719
5720         assert_return(m, -EINVAL);
5721         assert_return(source, -EINVAL);
5722         assert_return(!m->sealed, -EPERM);
5723         assert_return(source->sealed, -EPERM);
5724
5725         do {
5726                 const char *contents;
5727                 char type;
5728                 union {
5729                         uint8_t u8;
5730                         uint16_t u16;
5731                         int16_t s16;
5732                         uint32_t u32;
5733                         int32_t s32;
5734                         uint64_t u64;
5735                         int64_t s64;
5736                         double d64;
5737                         const char *string;
5738                         int i;
5739                 } basic;
5740
5741                 r = sd_bus_message_peek_type(source, &type, &contents);
5742                 if (r < 0)
5743                         return r;
5744                 if (r == 0)
5745                         break;
5746
5747                 done_something = true;
5748
5749                 if (bus_type_is_container(type) > 0) {
5750
5751                         r = sd_bus_message_enter_container(source, type, contents);
5752                         if (r < 0)
5753                                 return r;
5754
5755                         r = sd_bus_message_open_container(m, type, contents);
5756                         if (r < 0)
5757                                 return r;
5758
5759                         r = sd_bus_message_copy(m, source, true);
5760                         if (r < 0)
5761                                 return r;
5762
5763                         r = sd_bus_message_close_container(m);
5764                         if (r < 0)
5765                                 return r;
5766
5767                         r = sd_bus_message_exit_container(source);
5768                         if (r < 0)
5769                                 return r;
5770
5771                         continue;
5772                 }
5773
5774                 r = sd_bus_message_read_basic(source, type, &basic);
5775                 if (r < 0)
5776                         return r;
5777
5778                 assert(r > 0);
5779
5780                 if (IN_SET(type, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE, SD_BUS_TYPE_STRING))
5781                         r = sd_bus_message_append_basic(m, type, basic.string);
5782                 else
5783                         r = sd_bus_message_append_basic(m, type, &basic);
5784
5785                 if (r < 0)
5786                         return r;
5787
5788         } while (all);
5789
5790         return done_something;
5791 }
5792
5793 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5794         const char *c;
5795         char t;
5796         int r;
5797
5798         assert_return(m, -EINVAL);
5799         assert_return(m->sealed, -EPERM);
5800         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5801         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5802         assert_return(type || contents, -EINVAL);
5803         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5804
5805         r = sd_bus_message_peek_type(m, &t, &c);
5806         if (r <= 0)
5807                 return r;
5808
5809         if (type != 0 && type != t)
5810                 return 0;
5811
5812         if (contents && !streq_ptr(contents, c))
5813                 return 0;
5814
5815         return 1;
5816 }
5817
5818 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5819         assert_return(m, NULL);
5820
5821         return m->bus;
5822 }
5823
5824 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5825         _cleanup_(sd_bus_message_unrefp) sd_bus_message *n = NULL;
5826         usec_t timeout;
5827         int r;
5828
5829         assert(bus);
5830         assert(m);
5831         assert(*m);
5832
5833         switch ((*m)->header->type) {
5834
5835         case SD_BUS_MESSAGE_SIGNAL:
5836                 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5837                 if (r < 0)
5838                         return r;
5839
5840                 break;
5841
5842         case SD_BUS_MESSAGE_METHOD_CALL:
5843                 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5844                 if (r < 0)
5845                         return r;
5846
5847                 break;
5848
5849         case SD_BUS_MESSAGE_METHOD_RETURN:
5850         case SD_BUS_MESSAGE_METHOD_ERROR:
5851
5852                 n = message_new(bus, (*m)->header->type);
5853                 if (!n)
5854                         return -ENOMEM;
5855
5856                 n->reply_cookie = (*m)->reply_cookie;
5857
5858                 r = message_append_reply_cookie(n, n->reply_cookie);
5859                 if (r < 0)
5860                         return r;
5861
5862                 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5863                         r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5864                         if (r < 0)
5865                                 return r;
5866
5867                         n->error._need_free = -1;
5868                 }
5869
5870                 break;
5871
5872         default:
5873                 return -EINVAL;
5874         }
5875
5876         if ((*m)->destination && !n->destination) {
5877                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5878                 if (r < 0)
5879                         return r;
5880         }
5881
5882         if ((*m)->sender && !n->sender) {
5883                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5884                 if (r < 0)
5885                         return r;
5886         }
5887
5888         n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5889
5890         r = sd_bus_message_copy(n, *m, true);
5891         if (r < 0)
5892                 return r;
5893
5894         timeout = (*m)->timeout;
5895         if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5896                 timeout = BUS_DEFAULT_TIMEOUT;
5897
5898         r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5899         if (r < 0)
5900                 return r;
5901
5902         sd_bus_message_unref(*m);
5903         *m = n;
5904         n = NULL;
5905
5906         return 0;
5907 }
5908
5909 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5910         assert(m);
5911         assert(sender);
5912
5913         assert_return(!m->sealed, -EPERM);
5914         assert_return(!m->sender, -EPERM);
5915
5916         return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5917 }
5918
5919 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5920         assert_return(m, -EINVAL);
5921         assert_return(priority, -EINVAL);
5922
5923         *priority = m->priority;
5924         return 0;
5925 }
5926
5927 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5928         assert_return(m, -EINVAL);
5929         assert_return(!m->sealed, -EPERM);
5930
5931         m->priority = priority;
5932         return 0;
5933 }