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