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