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