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