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