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