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