chiark / gitweb /
bus: sync with kdbus-git (ABI break)
[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->data, part->mapped) == 0);
73
74                         safe_close(part->memfd);
75                 }
76
77         } else if (part->munmap_this)
78                 munmap(part->data, 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, part->memfd_offset);
1130                         else
1131                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1132
1133                         if (n == MAP_FAILED) {
1134                                 m->poisoned = true;
1135                                 return -errno;
1136                         }
1137
1138                         part->mapped = psz;
1139                         part->data = n;
1140                 }
1141
1142                 part->munmap_this = true;
1143         } else {
1144                 if (part->allocated == 0 || sz > part->allocated) {
1145                         size_t new_allocated;
1146
1147                         new_allocated = sz > 0 ? 2 * sz : 64;
1148                         n = realloc(part->data, new_allocated);
1149                         if (!n) {
1150                                 m->poisoned = true;
1151                                 return -ENOMEM;
1152                         }
1153
1154                         part->data = n;
1155                         part->allocated = new_allocated;
1156                         part->free_this = true;
1157                 }
1158         }
1159
1160         if (q)
1161                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1162
1163         part->size = sz;
1164         return 0;
1165 }
1166
1167 static int message_add_offset(sd_bus_message *m, size_t offset) {
1168         struct bus_container *c;
1169
1170         assert(m);
1171         assert(BUS_MESSAGE_IS_GVARIANT(m));
1172
1173         /* Add offset to current container, unless this is the first
1174          * item in it, which will have the 0 offset, which we can
1175          * ignore. */
1176         c = message_get_container(m);
1177
1178         if (!c->need_offsets)
1179                 return 0;
1180
1181         if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1182                 return -ENOMEM;
1183
1184         c->offsets[c->n_offsets++] = offset;
1185         return 0;
1186 }
1187
1188 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1189         struct bus_container *c;
1190
1191         assert(m);
1192
1193         if (expand <= 0)
1194                 return;
1195
1196         /* Update counters */
1197         for (c = m->containers; c < m->containers + m->n_containers; c++) {
1198
1199                 if (c->array_size)
1200                         *c->array_size += expand;
1201         }
1202 }
1203
1204 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
1205         size_t start_body, end_body, padding, added;
1206         void *p;
1207         int r;
1208
1209         assert(m);
1210         assert(align > 0);
1211         assert(!m->sealed);
1212
1213         if (m->poisoned)
1214                 return NULL;
1215
1216         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1217         end_body = start_body + sz;
1218
1219         padding = start_body - m->header->body_size;
1220         added = padding + sz;
1221
1222         /* Check for 32bit overflows */
1223         if (end_body > (size_t) ((uint32_t) -1)) {
1224                 m->poisoned = true;
1225                 return NULL;
1226         }
1227
1228         if (added > 0) {
1229                 struct bus_body_part *part = NULL;
1230                 bool add_new_part;
1231
1232                 add_new_part =
1233                         m->n_body_parts <= 0 ||
1234                         m->body_end->sealed ||
1235                         padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1236
1237                 if (add_new_part) {
1238                         if (padding > 0) {
1239                                 part = message_append_part(m);
1240                                 if (!part)
1241                                         return NULL;
1242
1243                                 part_zero(part, padding);
1244                         }
1245
1246                         part = message_append_part(m);
1247                         if (!part)
1248                                 return NULL;
1249
1250                         r = part_make_space(m, part, sz, &p);
1251                         if (r < 0)
1252                                 return NULL;
1253                 } else {
1254                         struct bus_container *c;
1255                         void *op;
1256                         size_t os, start_part, end_part;
1257
1258                         part = m->body_end;
1259                         op = part->data;
1260                         os = part->size;
1261
1262                         start_part = ALIGN_TO(part->size, align);
1263                         end_part = start_part + sz;
1264
1265                         r = part_make_space(m, part, end_part, &p);
1266                         if (r < 0)
1267                                 return NULL;
1268
1269                         if (padding > 0) {
1270                                 memzero(p, padding);
1271                                 p = (uint8_t*) p + padding;
1272                         }
1273
1274                         /* Readjust pointers */
1275                         for (c = m->containers; c < m->containers + m->n_containers; c++)
1276                                 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1277
1278                         m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1279                 }
1280         } else
1281                 /* Return something that is not NULL and is aligned */
1282                 p = (uint8_t *) NULL + align;
1283
1284         m->header->body_size = end_body;
1285         message_extend_containers(m, added);
1286
1287         if (add_offset) {
1288                 r = message_add_offset(m, end_body);
1289                 if (r < 0) {
1290                         m->poisoned = true;
1291                         return NULL;
1292                 }
1293         }
1294
1295         return p;
1296 }
1297
1298 static int message_push_fd(sd_bus_message *m, int fd) {
1299         int *f, copy;
1300
1301         assert(m);
1302
1303         if (fd < 0)
1304                 return -EINVAL;
1305
1306         if (!m->allow_fds)
1307                 return -ENOTSUP;
1308
1309         copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1310         if (copy < 0)
1311                 return -errno;
1312
1313         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1314         if (!f) {
1315                 m->poisoned = true;
1316                 safe_close(copy);
1317                 return -ENOMEM;
1318         }
1319
1320         m->fds = f;
1321         m->fds[m->n_fds] = copy;
1322         m->free_fds = true;
1323
1324         return copy;
1325 }
1326
1327 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1328         _cleanup_close_ int fd = -1;
1329         struct bus_container *c;
1330         ssize_t align, sz;
1331         void *a;
1332
1333         assert_return(m, -EINVAL);
1334         assert_return(!m->sealed, -EPERM);
1335         assert_return(bus_type_is_basic(type), -EINVAL);
1336         assert_return(!m->poisoned, -ESTALE);
1337
1338         c = message_get_container(m);
1339
1340         if (c->signature && c->signature[c->index]) {
1341                 /* Container signature is already set */
1342
1343                 if (c->signature[c->index] != type)
1344                         return -ENXIO;
1345         } else {
1346                 char *e;
1347
1348                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1349                 if (c->enclosing != 0)
1350                         return -ENXIO;
1351
1352                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1353                 if (!e) {
1354                         m->poisoned = true;
1355                         return -ENOMEM;
1356                 }
1357         }
1358
1359         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1360                 uint8_t u8;
1361                 uint32_t u32;
1362
1363                 switch (type) {
1364
1365                 case SD_BUS_TYPE_SIGNATURE:
1366                 case SD_BUS_TYPE_STRING:
1367                         p = strempty(p);
1368
1369                         /* Fall through... */
1370                 case SD_BUS_TYPE_OBJECT_PATH:
1371                         if (!p)
1372                                 return -EINVAL;
1373
1374                         align = 1;
1375                         sz = strlen(p) + 1;
1376                         break;
1377
1378                 case SD_BUS_TYPE_BOOLEAN:
1379
1380                         u8 = p && *(int*) p;
1381                         p = &u8;
1382
1383                         align = sz = 1;
1384                         break;
1385
1386                 case SD_BUS_TYPE_UNIX_FD:
1387
1388                         if (!p)
1389                                 return -EINVAL;
1390
1391                         fd = message_push_fd(m, *(int*) p);
1392                         if (fd < 0)
1393                                 return fd;
1394
1395                         u32 = m->n_fds;
1396                         p = &u32;
1397
1398                         align = sz = 4;
1399                         break;
1400
1401                 default:
1402                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1403                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1404                         break;
1405                 }
1406
1407                 assert(align > 0);
1408                 assert(sz > 0);
1409
1410                 a = message_extend_body(m, align, sz, true);
1411                 if (!a)
1412                         return -ENOMEM;
1413
1414                 memcpy(a, p, sz);
1415
1416                 if (stored)
1417                         *stored = (const uint8_t*) a;
1418
1419         } else {
1420                 uint32_t u32;
1421
1422                 switch (type) {
1423
1424                 case SD_BUS_TYPE_STRING:
1425                         /* To make things easy we'll serialize a NULL string
1426                          * into the empty string */
1427                         p = strempty(p);
1428
1429                         /* Fall through... */
1430                 case SD_BUS_TYPE_OBJECT_PATH:
1431
1432                         if (!p)
1433                                 return -EINVAL;
1434
1435                         align = 4;
1436                         sz = 4 + strlen(p) + 1;
1437                         break;
1438
1439                 case SD_BUS_TYPE_SIGNATURE:
1440
1441                         p = strempty(p);
1442
1443                         align = 1;
1444                         sz = 1 + strlen(p) + 1;
1445                         break;
1446
1447                 case SD_BUS_TYPE_BOOLEAN:
1448
1449                         u32 = p && *(int*) p;
1450                         p = &u32;
1451
1452                         align = sz = 4;
1453                         break;
1454
1455                 case SD_BUS_TYPE_UNIX_FD:
1456
1457                         if (!p)
1458                                 return -EINVAL;
1459
1460                         fd = message_push_fd(m, *(int*) p);
1461                         if (fd < 0)
1462                                 return fd;
1463
1464                         u32 = m->n_fds;
1465                         p = &u32;
1466
1467                         align = sz = 4;
1468                         break;
1469
1470                 default:
1471                         align = bus_type_get_alignment(type);
1472                         sz = bus_type_get_size(type);
1473                         break;
1474                 }
1475
1476                 assert(align > 0);
1477                 assert(sz > 0);
1478
1479                 a = message_extend_body(m, align, sz, false);
1480                 if (!a)
1481                         return -ENOMEM;
1482
1483                 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1484                         *(uint32_t*) a = sz - 5;
1485                         memcpy((uint8_t*) a + 4, p, sz - 4);
1486
1487                         if (stored)
1488                                 *stored = (const uint8_t*) a + 4;
1489
1490                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1491                         *(uint8_t*) a = sz - 2;
1492                         memcpy((uint8_t*) a + 1, p, sz - 1);
1493
1494                         if (stored)
1495                                 *stored = (const uint8_t*) a + 1;
1496                 } else {
1497                         memcpy(a, p, sz);
1498
1499                         if (stored)
1500                                 *stored = a;
1501                 }
1502         }
1503
1504         if (type == SD_BUS_TYPE_UNIX_FD)
1505                 m->n_fds ++;
1506
1507         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1508                 c->index++;
1509
1510         fd = -1;
1511         return 0;
1512 }
1513
1514 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1515         return message_append_basic(m, type, p, NULL);
1516 }
1517
1518 _public_ int sd_bus_message_append_string_space(
1519                 sd_bus_message *m,
1520                 size_t size,
1521                 char **s) {
1522
1523         struct bus_container *c;
1524         void *a;
1525
1526         assert_return(m, -EINVAL);
1527         assert_return(s, -EINVAL);
1528         assert_return(!m->sealed, -EPERM);
1529         assert_return(!m->poisoned, -ESTALE);
1530
1531         c = message_get_container(m);
1532
1533         if (c->signature && c->signature[c->index]) {
1534                 /* Container signature is already set */
1535
1536                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1537                         return -ENXIO;
1538         } else {
1539                 char *e;
1540
1541                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1542                 if (c->enclosing != 0)
1543                         return -ENXIO;
1544
1545                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1546                 if (!e) {
1547                         m->poisoned = true;
1548                         return -ENOMEM;
1549                 }
1550         }
1551
1552         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1553                 a = message_extend_body(m, 1, size + 1, true);
1554                 if (!a)
1555                         return -ENOMEM;
1556
1557                 *s = a;
1558         } else {
1559                 a = message_extend_body(m, 4, 4 + size + 1, false);
1560                 if (!a)
1561                         return -ENOMEM;
1562
1563                 *(uint32_t*) a = size;
1564                 *s = (char*) a + 4;
1565         }
1566
1567         (*s)[size] = 0;
1568
1569         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1570                 c->index++;
1571
1572         return 0;
1573 }
1574
1575 _public_ int sd_bus_message_append_string_iovec(
1576                 sd_bus_message *m,
1577                 const struct iovec *iov,
1578                 unsigned n) {
1579
1580         size_t size;
1581         unsigned i;
1582         char *p;
1583         int r;
1584
1585         assert_return(m, -EINVAL);
1586         assert_return(!m->sealed, -EPERM);
1587         assert_return(iov || n == 0, -EINVAL);
1588         assert_return(!m->poisoned, -ESTALE);
1589
1590         size = IOVEC_TOTAL_SIZE(iov, n);
1591
1592         r = sd_bus_message_append_string_space(m, size, &p);
1593         if (r < 0)
1594                 return r;
1595
1596         for (i = 0; i < n; i++) {
1597
1598                 if (iov[i].iov_base)
1599                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
1600                 else
1601                         memset(p, ' ', iov[i].iov_len);
1602
1603                 p += iov[i].iov_len;
1604         }
1605
1606         return 0;
1607 }
1608
1609 static int bus_message_open_array(
1610                 sd_bus_message *m,
1611                 struct bus_container *c,
1612                 const char *contents,
1613                 uint32_t **array_size,
1614                 size_t *begin,
1615                 bool *need_offsets) {
1616
1617         unsigned nindex;
1618         int alignment, r;
1619
1620         assert(m);
1621         assert(c);
1622         assert(contents);
1623         assert(array_size);
1624         assert(begin);
1625         assert(need_offsets);
1626
1627         if (!signature_is_single(contents, true))
1628                 return -EINVAL;
1629
1630         if (c->signature && c->signature[c->index]) {
1631
1632                 /* Verify the existing signature */
1633
1634                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1635                         return -ENXIO;
1636
1637                 if (!startswith(c->signature + c->index + 1, contents))
1638                         return -ENXIO;
1639
1640                 nindex = c->index + 1 + strlen(contents);
1641         } else {
1642                 char *e;
1643
1644                 if (c->enclosing != 0)
1645                         return -ENXIO;
1646
1647                 /* Extend the existing signature */
1648
1649                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1650                 if (!e) {
1651                         m->poisoned = true;
1652                         return -ENOMEM;
1653                 }
1654
1655                 nindex = e - c->signature;
1656         }
1657
1658         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1659                 alignment = bus_gvariant_get_alignment(contents);
1660                 if (alignment < 0)
1661                         return alignment;
1662
1663                 /* Add alignment padding and add to offset list */
1664                 if (!message_extend_body(m, alignment, 0, false))
1665                         return -ENOMEM;
1666
1667                 r = bus_gvariant_is_fixed_size(contents);
1668                 if (r < 0)
1669                         return r;
1670
1671                 *begin = m->header->body_size;
1672                 *need_offsets = r == 0;
1673         } else {
1674                 void *a, *op;
1675                 size_t os;
1676                 struct bus_body_part *o;
1677
1678                 alignment = bus_type_get_alignment(contents[0]);
1679                 if (alignment < 0)
1680                         return alignment;
1681
1682                 a = message_extend_body(m, 4, 4, false);
1683                 if (!a)
1684                         return -ENOMEM;
1685
1686                 o = m->body_end;
1687                 op = m->body_end->data;
1688                 os = m->body_end->size;
1689
1690                 /* Add alignment between size and first element */
1691                 if (!message_extend_body(m, alignment, 0, false))
1692                         return -ENOMEM;
1693
1694                 /* location of array size might have changed so let's readjust a */
1695                 if (o == m->body_end)
1696                         a = adjust_pointer(a, op, os, m->body_end->data);
1697
1698                 *(uint32_t*) a = 0;
1699                 *array_size = a;
1700         }
1701
1702         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1703                 c->index = nindex;
1704
1705         return 0;
1706 }
1707
1708 static int bus_message_open_variant(
1709                 sd_bus_message *m,
1710                 struct bus_container *c,
1711                 const char *contents) {
1712
1713         assert(m);
1714         assert(c);
1715         assert(contents);
1716
1717         if (!signature_is_single(contents, false))
1718                 return -EINVAL;
1719
1720         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1721                 return -EINVAL;
1722
1723         if (c->signature && c->signature[c->index]) {
1724
1725                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1726                         return -ENXIO;
1727
1728         } else {
1729                 char *e;
1730
1731                 if (c->enclosing != 0)
1732                         return -ENXIO;
1733
1734                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1735                 if (!e) {
1736                         m->poisoned = true;
1737                         return -ENOMEM;
1738                 }
1739         }
1740
1741         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1742                 /* Variants are always aligned to 8 */
1743
1744                 if (!message_extend_body(m, 8, 0, false))
1745                         return -ENOMEM;
1746
1747         } else {
1748                 size_t l;
1749                 void *a;
1750
1751                 l = strlen(contents);
1752                 a = message_extend_body(m, 1, 1 + l + 1, false);
1753                 if (!a)
1754                         return -ENOMEM;
1755
1756                 *(uint8_t*) a = l;
1757                 memcpy((uint8_t*) a + 1, contents, l + 1);
1758         }
1759
1760         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1761                 c->index++;
1762
1763         return 0;
1764 }
1765
1766 static int bus_message_open_struct(
1767                 sd_bus_message *m,
1768                 struct bus_container *c,
1769                 const char *contents,
1770                 size_t *begin,
1771                 bool *need_offsets) {
1772
1773         size_t nindex;
1774         int r;
1775
1776         assert(m);
1777         assert(c);
1778         assert(contents);
1779         assert(begin);
1780         assert(need_offsets);
1781
1782         if (!signature_is_valid(contents, false))
1783                 return -EINVAL;
1784
1785         if (c->signature && c->signature[c->index]) {
1786                 size_t l;
1787
1788                 l = strlen(contents);
1789
1790                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1791                     !startswith(c->signature + c->index + 1, contents) ||
1792                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1793                         return -ENXIO;
1794
1795                 nindex = c->index + 1 + l + 1;
1796         } else {
1797                 char *e;
1798
1799                 if (c->enclosing != 0)
1800                         return -ENXIO;
1801
1802                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1803                 if (!e) {
1804                         m->poisoned = true;
1805                         return -ENOMEM;
1806                 }
1807
1808                 nindex = e - c->signature;
1809         }
1810
1811         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1812                 int alignment;
1813
1814                 alignment = bus_gvariant_get_alignment(contents);
1815                 if (alignment < 0)
1816                         return alignment;
1817
1818                 if (!message_extend_body(m, alignment, 0, false))
1819                         return -ENOMEM;
1820
1821                 r = bus_gvariant_is_fixed_size(contents);
1822                 if (r < 0)
1823                         return r;
1824
1825                 *begin = m->header->body_size;
1826                 *need_offsets = r == 0;
1827         } else {
1828                 /* Align contents to 8 byte boundary */
1829                 if (!message_extend_body(m, 8, 0, false))
1830                         return -ENOMEM;
1831         }
1832
1833         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1834                 c->index = nindex;
1835
1836         return 0;
1837 }
1838
1839 static int bus_message_open_dict_entry(
1840                 sd_bus_message *m,
1841                 struct bus_container *c,
1842                 const char *contents,
1843                 size_t *begin,
1844                 bool *need_offsets) {
1845
1846         int r;
1847
1848         assert(m);
1849         assert(c);
1850         assert(contents);
1851         assert(begin);
1852         assert(need_offsets);
1853
1854         if (!signature_is_pair(contents))
1855                 return -EINVAL;
1856
1857         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1858                 return -ENXIO;
1859
1860         if (c->signature && c->signature[c->index]) {
1861                 size_t l;
1862
1863                 l = strlen(contents);
1864
1865                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1866                     !startswith(c->signature + c->index + 1, contents) ||
1867                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1868                         return -ENXIO;
1869         } else
1870                 return -ENXIO;
1871
1872         if (BUS_MESSAGE_IS_GVARIANT(m)) {
1873                 int alignment;
1874
1875                 alignment = bus_gvariant_get_alignment(contents);
1876                 if (alignment < 0)
1877                         return alignment;
1878
1879                 if (!message_extend_body(m, alignment, 0, false))
1880                         return -ENOMEM;
1881
1882                 r = bus_gvariant_is_fixed_size(contents);
1883                 if (r < 0)
1884                         return r;
1885
1886                 *begin = m->header->body_size;
1887                 *need_offsets = r == 0;
1888         } else {
1889                 /* Align contents to 8 byte boundary */
1890                 if (!message_extend_body(m, 8, 0, false))
1891                         return -ENOMEM;
1892         }
1893
1894         return 0;
1895 }
1896
1897 _public_ int sd_bus_message_open_container(
1898                 sd_bus_message *m,
1899                 char type,
1900                 const char *contents) {
1901
1902         struct bus_container *c, *w;
1903         uint32_t *array_size = NULL;
1904         char *signature;
1905         size_t before, begin = 0;
1906         bool need_offsets = false;
1907         int r;
1908
1909         assert_return(m, -EINVAL);
1910         assert_return(!m->sealed, -EPERM);
1911         assert_return(contents, -EINVAL);
1912         assert_return(!m->poisoned, -ESTALE);
1913
1914         /* Make sure we have space for one more container */
1915         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
1916                 m->poisoned = true;
1917                 return -ENOMEM;
1918         }
1919
1920         c = message_get_container(m);
1921
1922         signature = strdup(contents);
1923         if (!signature) {
1924                 m->poisoned = true;
1925                 return -ENOMEM;
1926         }
1927
1928         /* Save old index in the parent container, in case we have to
1929          * abort this container */
1930         c->saved_index = c->index;
1931         before = m->header->body_size;
1932
1933         if (type == SD_BUS_TYPE_ARRAY)
1934                 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
1935         else if (type == SD_BUS_TYPE_VARIANT)
1936                 r = bus_message_open_variant(m, c, contents);
1937         else if (type == SD_BUS_TYPE_STRUCT)
1938                 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
1939         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1940                 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
1941         else
1942                 r = -EINVAL;
1943
1944         if (r < 0) {
1945                 free(signature);
1946                 return r;
1947         }
1948
1949         /* OK, let's fill it in */
1950         w = m->containers + m->n_containers++;
1951         w->enclosing = type;
1952         w->signature = signature;
1953         w->index = 0;
1954         w->array_size = array_size;
1955         w->before = before;
1956         w->begin = begin;
1957         w->n_offsets = w->offsets_allocated = 0;
1958         w->offsets = NULL;
1959         w->need_offsets = need_offsets;
1960
1961         return 0;
1962 }
1963
1964 static size_t determine_word_size(size_t sz, size_t extra) {
1965         if (sz + extra <= 0xFF)
1966                 return 1;
1967         else if (sz + extra*2 <= 0xFFFF)
1968                 return 2;
1969         else if (sz + extra*4 <= 0xFFFFFFFF)
1970                 return 4;
1971         else
1972                 return 8;
1973 }
1974
1975 static size_t read_word_le(void *p, size_t sz) {
1976         union {
1977                 uint16_t u16;
1978                 uint32_t u32;
1979                 uint64_t u64;
1980         } x;
1981
1982         assert(p);
1983
1984         if (sz == 1)
1985                 return *(uint8_t*) p;
1986
1987         memcpy(&x, p, sz);
1988
1989         if (sz == 2)
1990                 return le16toh(x.u16);
1991         else if (sz == 4)
1992                 return le32toh(x.u32);
1993         else if (sz == 8)
1994                 return le64toh(x.u64);
1995
1996         assert_not_reached("unknown word width");
1997 }
1998
1999 static void write_word_le(void *p, size_t sz, size_t value) {
2000         union {
2001                 uint16_t u16;
2002                 uint32_t u32;
2003                 uint64_t u64;
2004         } x;
2005
2006         assert(p);
2007         assert(sz == 8 || (value < (1ULL << (sz*8))));
2008
2009         if (sz == 1) {
2010                 *(uint8_t*) p = value;
2011                 return;
2012         } else if (sz == 2)
2013                 x.u16 = htole16((uint16_t) value);
2014         else if (sz == 4)
2015                 x.u32 = htole32((uint32_t) value);
2016         else if (sz == 8)
2017                 x.u64 = htole64((uint64_t) value);
2018         else
2019                 assert_not_reached("unknown word width");
2020
2021         memcpy(p, &x, sz);
2022 }
2023
2024 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2025
2026         assert(m);
2027         assert(c);
2028
2029         if (!BUS_MESSAGE_IS_GVARIANT(m))
2030                 return 0;
2031
2032         if (c->need_offsets) {
2033                 size_t payload, sz, i;
2034                 uint8_t *a;
2035
2036                 /* Variable-width arrays */
2037
2038                 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2039                 sz = determine_word_size(payload, c->n_offsets);
2040
2041                 a = message_extend_body(m, 1, sz * c->n_offsets, true);
2042                 if (!a)
2043                         return -ENOMEM;
2044
2045                 for (i = 0; i < c->n_offsets; i++)
2046                         write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2047         } else {
2048                 void *a;
2049
2050                 /* Fixed-width or empty arrays */
2051
2052                 a = message_extend_body(m, 1, 0, true); /* let's add offset to parent */
2053                 if (!a)
2054                         return -ENOMEM;
2055         }
2056
2057         return 0;
2058 }
2059
2060 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2061         uint8_t *a;
2062         size_t l;
2063
2064         assert(m);
2065         assert(c);
2066         assert(c->signature);
2067
2068         if (!BUS_MESSAGE_IS_GVARIANT(m))
2069                 return 0;
2070
2071         l = strlen(c->signature);
2072
2073         a = message_extend_body(m, 1, 1 + l, true);
2074         if (!a)
2075                 return -ENOMEM;
2076
2077         a[0] = 0;
2078         memcpy(a+1, c->signature, l);
2079
2080         return 0;
2081 }
2082
2083 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2084         size_t n_variable = 0;
2085         unsigned i = 0;
2086         const char *p;
2087         uint8_t *a;
2088         int r;
2089
2090         assert(m);
2091         assert(c);
2092
2093         if (!BUS_MESSAGE_IS_GVARIANT(m))
2094                 return 0;
2095
2096         p = strempty(c->signature);
2097         while (*p != 0) {
2098                 size_t n;
2099
2100                 r = signature_element_length(p, &n);
2101                 if (r < 0)
2102                         return r;
2103                 else {
2104                         char t[n+1];
2105
2106                         memcpy(t, p, n);
2107                         t[n] = 0;
2108
2109                         r = bus_gvariant_is_fixed_size(t);
2110                         if (r < 0)
2111                                 return r;
2112                 }
2113
2114                 assert(!c->need_offsets || i <= c->n_offsets);
2115
2116                 /* We need to add an offset for each item that has a
2117                  * variable size and that is not the last one in the
2118                  * list */
2119                 if (r == 0 && p[n] != 0)
2120                         n_variable++;
2121
2122                 i++;
2123                 p += n;
2124         }
2125
2126         assert(!c->need_offsets || i == c->n_offsets);
2127         assert(c->need_offsets || n_variable == 0);
2128
2129         if (n_variable <= 0) {
2130                 a = message_extend_body(m, 1, 0, add_offset);
2131                 if (!a)
2132                         return -ENOMEM;
2133         } else {
2134                 size_t sz;
2135                 unsigned j;
2136
2137                 assert(c->offsets[c->n_offsets-1] == m->header->body_size);
2138
2139                 sz = determine_word_size(m->header->body_size - c->begin, n_variable);
2140
2141                 a = message_extend_body(m, 1, sz * n_variable, add_offset);
2142                 if (!a)
2143                         return -ENOMEM;
2144
2145                 p = strempty(c->signature);
2146                 for (i = 0, j = 0; i < c->n_offsets; i++) {
2147                         unsigned k;
2148                         size_t n;
2149
2150                         r = signature_element_length(p, &n);
2151                         if (r < 0)
2152                                 return r;
2153                         else {
2154                                 char t[n+1];
2155
2156                                 memcpy(t, p, n);
2157                                 t[n] = 0;
2158
2159                                 p += n;
2160
2161                                 r = bus_gvariant_is_fixed_size(t);
2162                                 if (r < 0)
2163                                         return r;
2164                                 if (r > 0 || p[0] == 0)
2165                                         continue;
2166                         }
2167
2168                         k = n_variable - 1 - j;
2169
2170                         write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2171
2172                         j++;
2173                 }
2174         }
2175
2176         return 0;
2177 }
2178
2179 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2180         struct bus_container *c;
2181         int r;
2182
2183         assert_return(m, -EINVAL);
2184         assert_return(!m->sealed, -EPERM);
2185         assert_return(m->n_containers > 0, -EINVAL);
2186         assert_return(!m->poisoned, -ESTALE);
2187
2188         c = message_get_container(m);
2189
2190         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2191                 if (c->signature && c->signature[c->index] != 0)
2192                         return -EINVAL;
2193
2194         m->n_containers--;
2195
2196         if (c->enclosing == SD_BUS_TYPE_ARRAY)
2197                 r = bus_message_close_array(m, c);
2198         else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2199                 r = bus_message_close_variant(m, c);
2200         else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2201                 r = bus_message_close_struct(m, c, true);
2202         else
2203                 assert_not_reached("Unknown container type");
2204
2205         free(c->signature);
2206         free(c->offsets);
2207
2208         return r;
2209 }
2210
2211 typedef struct {
2212         const char *types;
2213         unsigned n_struct;
2214         unsigned n_array;
2215 } TypeStack;
2216
2217 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2218         assert(stack);
2219         assert(max > 0);
2220
2221         if (*i >= max)
2222                 return -EINVAL;
2223
2224         stack[*i].types = types;
2225         stack[*i].n_struct = n_struct;
2226         stack[*i].n_array = n_array;
2227         (*i)++;
2228
2229         return 0;
2230 }
2231
2232 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2233         assert(stack);
2234         assert(max > 0);
2235         assert(types);
2236         assert(n_struct);
2237         assert(n_array);
2238
2239         if (*i <= 0)
2240                 return 0;
2241
2242         (*i)--;
2243         *types = stack[*i].types;
2244         *n_struct = stack[*i].n_struct;
2245         *n_array = stack[*i].n_array;
2246
2247         return 1;
2248 }
2249
2250 int bus_message_append_ap(
2251                 sd_bus_message *m,
2252                 const char *types,
2253                 va_list ap) {
2254
2255         unsigned n_array, n_struct;
2256         TypeStack stack[BUS_CONTAINER_DEPTH];
2257         unsigned stack_ptr = 0;
2258         int r;
2259
2260         assert(m);
2261
2262         if (!types)
2263                 return 0;
2264
2265         n_array = (unsigned) -1;
2266         n_struct = strlen(types);
2267
2268         for (;;) {
2269                 const char *t;
2270
2271                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2272                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2273                         if (r < 0)
2274                                 return r;
2275                         if (r == 0)
2276                                 break;
2277
2278                         r = sd_bus_message_close_container(m);
2279                         if (r < 0)
2280                                 return r;
2281
2282                         continue;
2283                 }
2284
2285                 t = types;
2286                 if (n_array != (unsigned) -1)
2287                         n_array --;
2288                 else {
2289                         types ++;
2290                         n_struct--;
2291                 }
2292
2293                 switch (*t) {
2294
2295                 case SD_BUS_TYPE_BYTE: {
2296                         uint8_t x;
2297
2298                         x = (uint8_t) va_arg(ap, int);
2299                         r = sd_bus_message_append_basic(m, *t, &x);
2300                         break;
2301                 }
2302
2303                 case SD_BUS_TYPE_BOOLEAN:
2304                 case SD_BUS_TYPE_INT32:
2305                 case SD_BUS_TYPE_UINT32:
2306                 case SD_BUS_TYPE_UNIX_FD: {
2307                         uint32_t x;
2308
2309                         /* We assume a boolean is the same as int32_t */
2310                         assert_cc(sizeof(int32_t) == sizeof(int));
2311
2312                         x = va_arg(ap, uint32_t);
2313                         r = sd_bus_message_append_basic(m, *t, &x);
2314                         break;
2315                 }
2316
2317                 case SD_BUS_TYPE_INT16:
2318                 case SD_BUS_TYPE_UINT16: {
2319                         uint16_t x;
2320
2321                         x = (uint16_t) va_arg(ap, int);
2322                         r = sd_bus_message_append_basic(m, *t, &x);
2323                         break;
2324                 }
2325
2326                 case SD_BUS_TYPE_INT64:
2327                 case SD_BUS_TYPE_UINT64:
2328                 case SD_BUS_TYPE_DOUBLE: {
2329                         uint64_t x;
2330
2331                         x = va_arg(ap, uint64_t);
2332                         r = sd_bus_message_append_basic(m, *t, &x);
2333                         break;
2334                 }
2335
2336                 case SD_BUS_TYPE_STRING:
2337                 case SD_BUS_TYPE_OBJECT_PATH:
2338                 case SD_BUS_TYPE_SIGNATURE: {
2339                         const char *x;
2340
2341                         x = va_arg(ap, const char*);
2342                         r = sd_bus_message_append_basic(m, *t, x);
2343                         break;
2344                 }
2345
2346                 case SD_BUS_TYPE_ARRAY: {
2347                         size_t k;
2348
2349                         r = signature_element_length(t + 1, &k);
2350                         if (r < 0)
2351                                 return r;
2352
2353                         {
2354                                 char s[k + 1];
2355                                 memcpy(s, t + 1, k);
2356                                 s[k] = 0;
2357
2358                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2359                                 if (r < 0)
2360                                         return r;
2361                         }
2362
2363                         if (n_array == (unsigned) -1) {
2364                                 types += k;
2365                                 n_struct -= k;
2366                         }
2367
2368                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2369                         if (r < 0)
2370                                 return r;
2371
2372                         types = t + 1;
2373                         n_struct = k;
2374                         n_array = va_arg(ap, unsigned);
2375
2376                         break;
2377                 }
2378
2379                 case SD_BUS_TYPE_VARIANT: {
2380                         const char *s;
2381
2382                         s = va_arg(ap, const char*);
2383                         if (!s)
2384                                 return -EINVAL;
2385
2386                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2387                         if (r < 0)
2388                                 return r;
2389
2390                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2391                         if (r < 0)
2392                                 return r;
2393
2394                         types = s;
2395                         n_struct = strlen(s);
2396                         n_array = (unsigned) -1;
2397
2398                         break;
2399                 }
2400
2401                 case SD_BUS_TYPE_STRUCT_BEGIN:
2402                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2403                         size_t k;
2404
2405                         r = signature_element_length(t, &k);
2406                         if (r < 0)
2407                                 return r;
2408
2409                         {
2410                                 char s[k - 1];
2411
2412                                 memcpy(s, t + 1, k - 2);
2413                                 s[k - 2] = 0;
2414
2415                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2416                                 if (r < 0)
2417                                         return r;
2418                         }
2419
2420                         if (n_array == (unsigned) -1) {
2421                                 types += k - 1;
2422                                 n_struct -= k - 1;
2423                         }
2424
2425                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2426                         if (r < 0)
2427                                 return r;
2428
2429                         types = t + 1;
2430                         n_struct = k - 2;
2431                         n_array = (unsigned) -1;
2432
2433                         break;
2434                 }
2435
2436                 default:
2437                         r = -EINVAL;
2438                 }
2439
2440                 if (r < 0)
2441                         return r;
2442         }
2443
2444         return 1;
2445 }
2446
2447 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2448         va_list ap;
2449         int r;
2450
2451         assert_return(m, -EINVAL);
2452         assert_return(types, -EINVAL);
2453         assert_return(!m->sealed, -EPERM);
2454         assert_return(!m->poisoned, -ESTALE);
2455
2456         va_start(ap, types);
2457         r = bus_message_append_ap(m, types, ap);
2458         va_end(ap);
2459
2460         return r;
2461 }
2462
2463 _public_ int sd_bus_message_append_array_space(
2464                 sd_bus_message *m,
2465                 char type,
2466                 size_t size,
2467                 void **ptr) {
2468
2469         ssize_t align, sz;
2470         void *a;
2471         int r;
2472
2473         assert_return(m, -EINVAL);
2474         assert_return(!m->sealed, -EPERM);
2475         assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2476         assert_return(ptr || size == 0, -EINVAL);
2477         assert_return(!m->poisoned, -ESTALE);
2478
2479         /* alignment and size of the trivial types (except bool) is
2480          * identical for gvariant and dbus1 marshalling */
2481         align = bus_type_get_alignment(type);
2482         sz = bus_type_get_size(type);
2483
2484         assert_se(align > 0);
2485         assert_se(sz > 0);
2486
2487         if (size % sz != 0)
2488                 return -EINVAL;
2489
2490         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2491         if (r < 0)
2492                 return r;
2493
2494         a = message_extend_body(m, align, size, false);
2495         if (!a)
2496                 return -ENOMEM;
2497
2498         r = sd_bus_message_close_container(m);
2499         if (r < 0)
2500                 return r;
2501
2502         *ptr = a;
2503         return 0;
2504 }
2505
2506 _public_ int sd_bus_message_append_array(sd_bus_message *m,
2507                                          char type,
2508                                          const void *ptr,
2509                                          size_t size) {
2510         int r;
2511         void *p;
2512
2513         assert_return(m, -EINVAL);
2514         assert_return(!m->sealed, -EPERM);
2515         assert_return(bus_type_is_trivial(type), -EINVAL);
2516         assert_return(ptr || size == 0, -EINVAL);
2517         assert_return(!m->poisoned, -ESTALE);
2518
2519         r = sd_bus_message_append_array_space(m, type, size, &p);
2520         if (r < 0)
2521                 return r;
2522
2523         if (size > 0)
2524                 memcpy(p, ptr, size);
2525
2526         return 0;
2527 }
2528
2529 _public_ int sd_bus_message_append_array_iovec(
2530                 sd_bus_message *m,
2531                 char type,
2532                 const struct iovec *iov,
2533                 unsigned n) {
2534
2535         size_t size;
2536         unsigned i;
2537         void *p;
2538         int r;
2539
2540         assert_return(m, -EINVAL);
2541         assert_return(!m->sealed, -EPERM);
2542         assert_return(bus_type_is_trivial(type), -EINVAL);
2543         assert_return(iov || n == 0, -EINVAL);
2544         assert_return(!m->poisoned, -ESTALE);
2545
2546         size = IOVEC_TOTAL_SIZE(iov, n);
2547
2548         r = sd_bus_message_append_array_space(m, type, size, &p);
2549         if (r < 0)
2550                 return r;
2551
2552         for (i = 0; i < n; i++) {
2553
2554                 if (iov[i].iov_base)
2555                         memcpy(p, iov[i].iov_base, iov[i].iov_len);
2556                 else
2557                         memzero(p, iov[i].iov_len);
2558
2559                 p = (uint8_t*) p + iov[i].iov_len;
2560         }
2561
2562         return 0;
2563 }
2564
2565 _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
2566                                                char type,
2567                                                int memfd) {
2568         _cleanup_close_ int copy_fd = -1;
2569         struct bus_body_part *part;
2570         ssize_t align, sz;
2571         uint64_t size;
2572         void *a;
2573         int r;
2574
2575         if (!m)
2576                 return -EINVAL;
2577         if (memfd < 0)
2578                 return -EINVAL;
2579         if (m->sealed)
2580                 return -EPERM;
2581         if (!bus_type_is_trivial(type))
2582                 return -EINVAL;
2583         if (m->poisoned)
2584                 return -ESTALE;
2585
2586         r = memfd_set_sealed(memfd);
2587         if (r < 0)
2588                 return r;
2589
2590         copy_fd = dup(memfd);
2591         if (copy_fd < 0)
2592                 return copy_fd;
2593
2594         r = memfd_get_size(memfd, &size);
2595         if (r < 0)
2596                 return r;
2597
2598         align = bus_type_get_alignment(type);
2599         sz = bus_type_get_size(type);
2600
2601         assert_se(align > 0);
2602         assert_se(sz > 0);
2603
2604         if (size % sz != 0)
2605                 return -EINVAL;
2606
2607         if (size > (uint64_t) (uint32_t) -1)
2608                 return -EINVAL;
2609
2610         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2611         if (r < 0)
2612                 return r;
2613
2614         a = message_extend_body(m, align, 0, false);
2615         if (!a)
2616                 return -ENOMEM;
2617
2618         part = message_append_part(m);
2619         if (!part)
2620                 return -ENOMEM;
2621
2622         part->memfd = copy_fd;
2623         part->memfd_offset = 0;
2624         part->sealed = true;
2625         part->size = size;
2626         copy_fd = -1;
2627
2628         m->header->body_size += size;
2629         message_extend_containers(m, size);
2630
2631         return sd_bus_message_close_container(m);
2632 }
2633
2634 _public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
2635         _cleanup_close_ int copy_fd = -1;
2636         struct bus_body_part *part;
2637         struct bus_container *c;
2638         uint64_t size;
2639         void *a;
2640         int r;
2641
2642         assert_return(m, -EINVAL);
2643         assert_return(memfd >= 0, -EINVAL);
2644         assert_return(!m->sealed, -EPERM);
2645         assert_return(!m->poisoned, -ESTALE);
2646
2647         r = memfd_set_sealed(memfd);
2648         if (r < 0)
2649                 return r;
2650
2651         copy_fd = dup(memfd);
2652         if (copy_fd < 0)
2653                 return copy_fd;
2654
2655         r = memfd_get_size(memfd, &size);
2656         if (r < 0)
2657                 return r;
2658
2659         /* We require this to be NUL terminated */
2660         if (size == 0)
2661                 return -EINVAL;
2662
2663         if (size > (uint64_t) (uint32_t) -1)
2664                 return -EINVAL;
2665
2666         c = message_get_container(m);
2667         if (c->signature && c->signature[c->index]) {
2668                 /* Container signature is already set */
2669
2670                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2671                         return -ENXIO;
2672         } else {
2673                 char *e;
2674
2675                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2676                 if (c->enclosing != 0)
2677                         return -ENXIO;
2678
2679                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2680                 if (!e) {
2681                         m->poisoned = true;
2682                         return -ENOMEM;
2683                 }
2684         }
2685
2686         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2687                 a = message_extend_body(m, 4, 4, false);
2688                 if (!a)
2689                         return -ENOMEM;
2690
2691                 *(uint32_t*) a = size - 1;
2692         }
2693
2694         part = message_append_part(m);
2695         if (!part)
2696                 return -ENOMEM;
2697
2698         part->memfd = copy_fd;
2699         part->memfd_offset = 0;
2700         part->sealed = true;
2701         part->size = size;
2702         copy_fd = -1;
2703
2704         m->header->body_size += size;
2705         message_extend_containers(m, size);
2706
2707         if (BUS_MESSAGE_IS_GVARIANT(m)) {
2708                 r = message_add_offset(m, m->header->body_size);
2709                 if (r < 0) {
2710                         m->poisoned = true;
2711                         return -ENOMEM;
2712                 }
2713         }
2714
2715         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2716                 c->index++;
2717
2718         return 0;
2719 }
2720
2721 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2722         char **i;
2723         int r;
2724
2725         assert_return(m, -EINVAL);
2726         assert_return(!m->sealed, -EPERM);
2727         assert_return(!m->poisoned, -ESTALE);
2728
2729         r = sd_bus_message_open_container(m, 'a', "s");
2730         if (r < 0)
2731                 return r;
2732
2733         STRV_FOREACH(i, l) {
2734                 r = sd_bus_message_append_basic(m, 's', *i);
2735                 if (r < 0)
2736                         return r;
2737         }
2738
2739         return sd_bus_message_close_container(m);
2740 }
2741
2742 static int bus_message_close_header(sd_bus_message *m) {
2743         uint8_t *a;
2744         size_t sz, i;
2745
2746         assert(m);
2747
2748         if (!BUS_MESSAGE_IS_GVARIANT(m))
2749                 return 0;
2750
2751         if (m->n_header_offsets < 1)
2752                 return 0;
2753
2754         assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
2755
2756         sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
2757
2758         a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2759         if (!a)
2760                 return -ENOMEM;
2761
2762         for (i = 0; i < m->n_header_offsets; i++)
2763                 write_word_le(a + sz*i, sz, m->header_offsets[i]);
2764
2765         return 0;
2766 }
2767
2768 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2769         struct bus_body_part *part;
2770         size_t l, a;
2771         unsigned i;
2772         int r;
2773
2774         assert(m);
2775
2776         if (m->sealed)
2777                 return -EPERM;
2778
2779         if (m->n_containers > 0)
2780                 return -EBADMSG;
2781
2782         if (m->poisoned)
2783                 return -ESTALE;
2784
2785         /* In vtables the return signature of method calls is listed,
2786          * let's check if they match if this is a response */
2787         if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2788             m->enforced_reply_signature &&
2789             !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2790                 return -ENOMSG;
2791
2792         /* If gvariant marshalling is used we need to close the body structure */
2793         r = bus_message_close_struct(m, &m->root_container, false);
2794         if (r < 0)
2795                 return r;
2796
2797         /* If there's a non-trivial signature set, then add it in here */
2798         if (!isempty(m->root_container.signature)) {
2799                 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2800                 if (r < 0)
2801                         return r;
2802         }
2803
2804         if (m->n_fds > 0) {
2805                 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2806                 if (r < 0)
2807                         return r;
2808         }
2809
2810         r = bus_message_close_header(m);
2811         if (r < 0)
2812                 return r;
2813
2814         m->header->serial = (uint32_t) cookie;
2815         m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2816
2817         /* Add padding at the end of the fields part, since we know
2818          * the body needs to start at an 8 byte alignment. We made
2819          * sure we allocated enough space for this, so all we need to
2820          * do here is to zero it out. */
2821         l = BUS_MESSAGE_FIELDS_SIZE(m);
2822         a = ALIGN8(l) - l;
2823         if (a > 0)
2824                 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
2825
2826         /* If this is something we can send as memfd, then let's seal
2827         the memfd now. Note that we can send memfds as payload only
2828         for directed messages, and not for broadcasts. */
2829         if (m->destination && m->bus->use_memfd) {
2830                 MESSAGE_FOREACH_PART(part, i, m)
2831                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
2832                                 uint64_t sz;
2833
2834                                 /* Try to seal it if that makes
2835                                  * sense. First, unmap our own map to
2836                                  * make sure we don't keep it busy. */
2837                                 bus_body_part_unmap(part);
2838
2839                                 /* Then, sync up real memfd size */
2840                                 sz = part->size;
2841                                 r = memfd_set_size(part->memfd, sz);
2842                                 if (r < 0)
2843                                         return r;
2844
2845                                 /* Finally, try to seal */
2846                                 if (memfd_set_sealed(part->memfd) >= 0)
2847                                         part->sealed = true;
2848                         }
2849         }
2850
2851         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
2852         m->root_container.index = 0;
2853         m->root_container.offset_index = 0;
2854         m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
2855
2856         m->sealed = true;
2857
2858         return 0;
2859 }
2860
2861 int bus_body_part_map(struct bus_body_part *part) {
2862         void *p;
2863         size_t psz;
2864
2865         assert_se(part);
2866
2867         if (part->data)
2868                 return 0;
2869
2870         if (part->size <= 0)
2871                 return 0;
2872
2873         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2874         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2875                 static const uint8_t zeroes[7] = { };
2876                 part->data = (void*) zeroes;
2877                 return 0;
2878         }
2879
2880         psz = PAGE_ALIGN(part->size);
2881
2882         if (part->memfd >= 0)
2883                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset);
2884         else if (part->is_zero)
2885                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2886         else
2887                 return -EINVAL;
2888
2889         if (p == MAP_FAILED)
2890                 return -errno;
2891
2892         part->mapped = psz;
2893         part->data = p;
2894         part->munmap_this = true;
2895
2896         return 0;
2897 }
2898
2899 void bus_body_part_unmap(struct bus_body_part *part) {
2900
2901         assert_se(part);
2902
2903         if (part->memfd < 0)
2904                 return;
2905
2906         if (!part->data)
2907                 return;
2908
2909         if (!part->munmap_this)
2910                 return;
2911
2912         assert_se(munmap(part->data, part->mapped) == 0);
2913
2914         part->data = NULL;
2915         part->mapped = 0;
2916         part->munmap_this = false;
2917
2918         return;
2919 }
2920
2921 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2922         size_t k, start, end;
2923
2924         assert(rindex);
2925         assert(align > 0);
2926
2927         start = ALIGN_TO((size_t) *rindex, align);
2928         end = start + nbytes;
2929
2930         if (end > sz)
2931                 return -EBADMSG;
2932
2933         /* Verify that padding is 0 */
2934         for (k = *rindex; k < start; k++)
2935                 if (((const uint8_t*) p)[k] != 0)
2936                         return -EBADMSG;
2937
2938         if (r)
2939                 *r = (uint8_t*) p + start;
2940
2941         *rindex = end;
2942
2943         return 1;
2944 }
2945
2946 static bool message_end_of_signature(sd_bus_message *m) {
2947         struct bus_container *c;
2948
2949         assert(m);
2950
2951         c = message_get_container(m);
2952         return !c->signature || c->signature[c->index] == 0;
2953 }
2954
2955 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2956         struct bus_container *c;
2957
2958         assert(m);
2959
2960         c = message_get_container(m);
2961         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2962                 return false;
2963
2964         if (BUS_MESSAGE_IS_GVARIANT(m))
2965                 return index >= c->end;
2966         else {
2967                 assert(c->array_size);
2968                 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2969         }
2970 }
2971
2972 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2973         assert_return(m, -EINVAL);
2974         assert_return(m->sealed, -EPERM);
2975
2976         if (complete && m->n_containers > 0)
2977                 return false;
2978
2979         if (message_end_of_signature(m))
2980                 return true;
2981
2982         if (message_end_of_array(m, m->rindex))
2983                 return true;
2984
2985         return false;
2986 }
2987
2988 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2989         struct bus_body_part *part;
2990         size_t begin;
2991         int r;
2992
2993         assert(m);
2994
2995         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2996                 part = m->cached_rindex_part;
2997                 begin = m->cached_rindex_part_begin;
2998         } else {
2999                 part = &m->body;
3000                 begin = 0;
3001         }
3002
3003         while (part) {
3004                 if (index < begin)
3005                         return NULL;
3006
3007                 if (index + sz <= begin + part->size) {
3008
3009                         r = bus_body_part_map(part);
3010                         if (r < 0)
3011                                 return NULL;
3012
3013                         if (p)
3014                                 *p = (uint8_t*) part->data + index - begin;
3015
3016                         m->cached_rindex_part = part;
3017                         m->cached_rindex_part_begin = begin;
3018
3019                         return part;
3020                 }
3021
3022                 begin += part->size;
3023                 part = part->next;
3024         }
3025
3026         return NULL;
3027 }
3028
3029 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3030         int r;
3031
3032         assert(m);
3033         assert(c);
3034         assert(rindex);
3035
3036         if (!BUS_MESSAGE_IS_GVARIANT(m))
3037                 return 0;
3038
3039         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3040                 int sz;
3041
3042                 sz = bus_gvariant_get_size(c->signature);
3043                 if (sz < 0) {
3044                         int alignment;
3045
3046                         if (c->offset_index+1 >= c->n_offsets)
3047                                 goto end;
3048
3049                         /* Variable-size array */
3050
3051                         alignment = bus_gvariant_get_alignment(c->signature);
3052                         assert(alignment > 0);
3053
3054                         *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3055                         c->item_size = c->offsets[c->offset_index+1] - *rindex;
3056                 } else {
3057
3058                         if (c->offset_index+1 >= (c->end-c->begin)/sz)
3059                                 goto end;
3060
3061                         /* Fixed-size array */
3062                         *rindex = c->begin + (c->offset_index+1) * sz;
3063                         c->item_size = sz;
3064                 }
3065
3066                 c->offset_index++;
3067
3068         } else if (c->enclosing == 0 ||
3069                    c->enclosing == SD_BUS_TYPE_STRUCT ||
3070                    c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3071
3072                 int alignment;
3073                 size_t n, j;
3074
3075                 if (c->offset_index+1 >= c->n_offsets)
3076                         goto end;
3077
3078                 r = signature_element_length(c->signature + c->index, &n);
3079                 if (r < 0)
3080                         return r;
3081
3082                 r = signature_element_length(c->signature + c->index + n, &j);
3083                 if (r < 0)
3084                         return r;
3085                 else {
3086                         char t[j+1];
3087                         memcpy(t, c->signature + c->index + n, j);
3088                         t[j] = 0;
3089
3090                         alignment = bus_gvariant_get_alignment(t);
3091                 }
3092
3093                 assert(alignment > 0);
3094
3095                 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3096                 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3097
3098                 c->offset_index++;
3099
3100         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3101                 goto end;
3102         else
3103                 assert_not_reached("Unknown container type");
3104
3105         return 0;
3106
3107 end:
3108         /* Reached the end */
3109         *rindex = c->end;
3110         c->item_size = 0;
3111         return 0;
3112 }
3113
3114
3115 static int message_peek_body(
3116                 sd_bus_message *m,
3117                 size_t *rindex,
3118                 size_t align,
3119                 size_t nbytes,
3120                 void **ret) {
3121
3122         size_t k, start, end, padding;
3123         struct bus_body_part *part;
3124         uint8_t *q;
3125
3126         assert(m);
3127         assert(rindex);
3128         assert(align > 0);
3129
3130         start = ALIGN_TO((size_t) *rindex, align);
3131         padding = start - *rindex;
3132         end = start + nbytes;
3133
3134         if (end > BUS_MESSAGE_BODY_SIZE(m))
3135                 return -EBADMSG;
3136
3137         part = find_part(m, *rindex, padding, (void**) &q);
3138         if (!part)
3139                 return -EBADMSG;
3140
3141         if (q) {
3142                 /* Verify padding */
3143                 for (k = 0; k < padding; k++)
3144                         if (q[k] != 0)
3145                                 return -EBADMSG;
3146         }
3147
3148         part = find_part(m, start, nbytes, (void**) &q);
3149         if (!part || (nbytes > 0 && !q))
3150                 return -EBADMSG;
3151
3152         *rindex = end;
3153
3154         if (ret)
3155                 *ret = q;
3156
3157         return 0;
3158 }
3159
3160 static bool validate_nul(const char *s, size_t l) {
3161
3162         /* Check for NUL chars in the string */
3163         if (memchr(s, 0, l))
3164                 return false;
3165
3166         /* Check for NUL termination */
3167         if (s[l] != 0)
3168                 return false;
3169
3170         return true;
3171 }
3172
3173 static bool validate_string(const char *s, size_t l) {
3174
3175         if (!validate_nul(s, l))
3176                 return false;
3177
3178         /* Check if valid UTF8 */
3179         if (!utf8_is_valid(s))
3180                 return false;
3181
3182         return true;
3183 }
3184
3185 static bool validate_signature(const char *s, size_t l) {
3186
3187         if (!validate_nul(s, l))
3188                 return false;
3189
3190         /* Check if valid signature */
3191         if (!signature_is_valid(s, true))
3192                 return false;
3193
3194         return true;
3195 }
3196
3197 static bool validate_object_path(const char *s, size_t l) {
3198
3199         if (!validate_nul(s, l))
3200                 return false;
3201
3202         if (!object_path_is_valid(s))
3203                 return false;
3204
3205         return true;
3206 }
3207
3208 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3209         struct bus_container *c;
3210         size_t rindex;
3211         void *q;
3212         int r;
3213
3214         assert_return(m, -EINVAL);
3215         assert_return(m->sealed, -EPERM);
3216         assert_return(bus_type_is_basic(type), -EINVAL);
3217
3218         if (message_end_of_signature(m))
3219                 return -ENXIO;
3220
3221         if (message_end_of_array(m, m->rindex))
3222                 return 0;
3223
3224         c = message_get_container(m);
3225         if (c->signature[c->index] != type)
3226                 return -ENXIO;
3227
3228         rindex = m->rindex;
3229
3230         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3231
3232                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3233                         bool ok;
3234
3235                         r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3236                         if (r < 0)
3237                                 return r;
3238
3239                         if (type == SD_BUS_TYPE_STRING)
3240                                 ok = validate_string(q, c->item_size-1);
3241                         else if (type == SD_BUS_TYPE_OBJECT_PATH)
3242                                 ok = validate_object_path(q, c->item_size-1);
3243                         else
3244                                 ok = validate_signature(q, c->item_size-1);
3245
3246                         if (!ok)
3247                                 return -EBADMSG;
3248
3249                         if (p)
3250                                 *(const char**) p = q;
3251                 } else {
3252                         int sz, align;
3253
3254                         sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3255                         assert(sz > 0);
3256                         if ((size_t) sz != c->item_size)
3257                                 return -EBADMSG;
3258
3259                         align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3260                         assert(align > 0);
3261
3262                         r = message_peek_body(m, &rindex, align, c->item_size, &q);
3263                         if (r < 0)
3264                                 return r;
3265
3266                         switch (type) {
3267
3268                         case SD_BUS_TYPE_BYTE:
3269                                 if (p)
3270                                         *(uint8_t*) p = *(uint8_t*) q;
3271                                 break;
3272
3273                         case SD_BUS_TYPE_BOOLEAN:
3274                                 if (p)
3275                                         *(int*) p = !!*(uint8_t*) q;
3276                                 break;
3277
3278                         case SD_BUS_TYPE_INT16:
3279                         case SD_BUS_TYPE_UINT16:
3280                                 if (p)
3281                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3282                                 break;
3283
3284                         case SD_BUS_TYPE_INT32:
3285                         case SD_BUS_TYPE_UINT32:
3286                                 if (p)
3287                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3288                                 break;
3289
3290                         case SD_BUS_TYPE_INT64:
3291                         case SD_BUS_TYPE_UINT64:
3292                         case SD_BUS_TYPE_DOUBLE:
3293                                 if (p)
3294                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3295                                 break;
3296
3297                         case SD_BUS_TYPE_UNIX_FD: {
3298                                 uint32_t j;
3299
3300                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3301                                 if (j >= m->n_fds)
3302                                         return -EBADMSG;
3303
3304                                 if (p)
3305                                         *(int*) p = m->fds[j];
3306
3307                                 break;
3308                         }
3309
3310                         default:
3311                                 assert_not_reached("unexpected type");
3312                         }
3313                 }
3314
3315                 r = container_next_item(m, c, &rindex);
3316                 if (r < 0)
3317                         return r;
3318         } else {
3319
3320                 rindex = m->rindex;
3321
3322                 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3323                         uint32_t l;
3324                         bool ok;
3325
3326                         r = message_peek_body(m, &rindex, 4, 4, &q);
3327                         if (r < 0)
3328                                 return r;
3329
3330                         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3331                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3332                         if (r < 0)
3333                                 return r;
3334
3335                         if (type == SD_BUS_TYPE_OBJECT_PATH)
3336                                 ok = validate_object_path(q, l);
3337                         else
3338                                 ok = validate_string(q, l);
3339                         if (!ok)
3340                                 return -EBADMSG;
3341
3342                         if (p)
3343                                 *(const char**) p = q;
3344
3345                 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3346                         uint8_t l;
3347
3348                         r = message_peek_body(m, &rindex, 1, 1, &q);
3349                         if (r < 0)
3350                                 return r;
3351
3352                         l = *(uint8_t*) q;
3353                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3354                         if (r < 0)
3355                                 return r;
3356
3357                         if (!validate_signature(q, l))
3358                                 return -EBADMSG;
3359
3360                         if (p)
3361                                 *(const char**) p = q;
3362
3363                 } else {
3364                         ssize_t sz, align;
3365
3366                         align = bus_type_get_alignment(type);
3367                         assert(align > 0);
3368
3369                         sz = bus_type_get_size(type);
3370                         assert(sz > 0);
3371
3372                         r = message_peek_body(m, &rindex, align, sz, &q);
3373                         if (r < 0)
3374                                 return r;
3375
3376                         switch (type) {
3377
3378                         case SD_BUS_TYPE_BYTE:
3379                                 if (p)
3380                                         *(uint8_t*) p = *(uint8_t*) q;
3381                                 break;
3382
3383                         case SD_BUS_TYPE_BOOLEAN:
3384                                 if (p)
3385                                         *(int*) p = !!*(uint32_t*) q;
3386                                 break;
3387
3388                         case SD_BUS_TYPE_INT16:
3389                         case SD_BUS_TYPE_UINT16:
3390                                 if (p)
3391                                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3392                                 break;
3393
3394                         case SD_BUS_TYPE_INT32:
3395                         case SD_BUS_TYPE_UINT32:
3396                                 if (p)
3397                                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3398                                 break;
3399
3400                         case SD_BUS_TYPE_INT64:
3401                         case SD_BUS_TYPE_UINT64:
3402                         case SD_BUS_TYPE_DOUBLE:
3403                                 if (p)
3404                                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3405                                 break;
3406
3407                         case SD_BUS_TYPE_UNIX_FD: {
3408                                 uint32_t j;
3409
3410                                 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3411                                 if (j >= m->n_fds)
3412                                         return -EBADMSG;
3413
3414                                 if (p)
3415                                         *(int*) p = m->fds[j];
3416                                 break;
3417                         }
3418
3419                         default:
3420                                 assert_not_reached("Unknown basic type...");
3421                         }
3422                 }
3423         }
3424
3425         m->rindex = rindex;
3426
3427         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3428                 c->index++;
3429
3430         return 1;
3431 }
3432
3433 static int bus_message_enter_array(
3434                 sd_bus_message *m,
3435                 struct bus_container *c,
3436                 const char *contents,
3437                 uint32_t **array_size,
3438                 size_t *item_size,
3439                 size_t **offsets,
3440                 size_t *n_offsets) {
3441
3442         size_t rindex;
3443         void *q;
3444         int r, alignment;
3445
3446         assert(m);
3447         assert(c);
3448         assert(contents);
3449         assert(array_size);
3450         assert(item_size);
3451         assert(offsets);
3452         assert(n_offsets);
3453
3454         if (!signature_is_single(contents, true))
3455                 return -EINVAL;
3456
3457         if (!c->signature || c->signature[c->index] == 0)
3458                 return -ENXIO;
3459
3460         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3461                 return -ENXIO;
3462
3463         if (!startswith(c->signature + c->index + 1, contents))
3464                 return -ENXIO;
3465
3466         rindex = m->rindex;
3467
3468         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3469                 /* dbus1 */
3470
3471                 r = message_peek_body(m, &rindex, 4, 4, &q);
3472                 if (r < 0)
3473                         return r;
3474
3475                 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3476                         return -EBADMSG;
3477
3478                 alignment = bus_type_get_alignment(contents[0]);
3479                 if (alignment < 0)
3480                         return alignment;
3481
3482                 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3483                 if (r < 0)
3484                         return r;
3485
3486                 *array_size = (uint32_t*) q;
3487
3488         } else if (c->item_size <= 0) {
3489
3490                 /* gvariant: empty array */
3491                 *item_size = 0;
3492                 *offsets = NULL;
3493                 *n_offsets = 0;
3494
3495         } else if (bus_gvariant_is_fixed_size(contents)) {
3496
3497                 /* gvariant: fixed length array */
3498                 *item_size = bus_gvariant_get_size(contents);
3499                 *offsets = NULL;
3500                 *n_offsets = 0;
3501
3502         } else {
3503                 size_t where, p = 0, framing, sz;
3504                 unsigned i;
3505
3506                 /* gvariant: variable length array */
3507                 sz = determine_word_size(c->item_size, 0);
3508
3509                 where = rindex + c->item_size - sz;
3510                 r = message_peek_body(m, &where, 1, sz, &q);
3511                 if (r < 0)
3512                         return r;
3513
3514                 framing = read_word_le(q, sz);
3515                 if (framing > c->item_size - sz)
3516                         return -EBADMSG;
3517                 if ((c->item_size - framing) % sz != 0)
3518                         return -EBADMSG;
3519
3520                 *n_offsets = (c->item_size - framing) / sz;
3521
3522                 where = rindex + framing;
3523                 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3524                 if (r < 0)
3525                         return r;
3526
3527                 *offsets = new(size_t, *n_offsets);
3528                 if (!*offsets)
3529                         return -ENOMEM;
3530
3531                 for (i = 0; i < *n_offsets; i++) {
3532                         size_t x;
3533
3534                         x = read_word_le((uint8_t*) q + i * sz, sz);
3535                         if (x > c->item_size - sz)
3536                                 return -EBADMSG;
3537                         if (x < p)
3538                                 return -EBADMSG;
3539
3540                         (*offsets)[i] = rindex + x;
3541                         p = x;
3542                 }
3543
3544                 *item_size = (*offsets)[0] - rindex;
3545         }
3546
3547         m->rindex = rindex;
3548
3549         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3550                 c->index += 1 + strlen(contents);
3551
3552         return 1;
3553 }
3554
3555 static int bus_message_enter_variant(
3556                 sd_bus_message *m,
3557                 struct bus_container *c,
3558                 const char *contents,
3559                 size_t *item_size) {
3560
3561         size_t rindex;
3562         uint8_t l;
3563         void *q;
3564         int r;
3565
3566         assert(m);
3567         assert(c);
3568         assert(contents);
3569         assert(item_size);
3570
3571         if (!signature_is_single(contents, false))
3572                 return -EINVAL;
3573
3574         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3575                 return -EINVAL;
3576
3577         if (!c->signature || c->signature[c->index] == 0)
3578                 return -ENXIO;
3579
3580         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3581                 return -ENXIO;
3582
3583         rindex = m->rindex;
3584
3585         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3586                 size_t k, where;
3587
3588                 k = strlen(contents);
3589                 if (1+k > c->item_size)
3590                         return -EBADMSG;
3591
3592                 where = rindex + c->item_size - (1+k);
3593                 r = message_peek_body(m, &where, 1, 1+k, &q);
3594                 if (r < 0)
3595                         return r;
3596
3597                 if (*(char*) q != 0)
3598                         return -EBADMSG;
3599
3600                 if (memcmp((uint8_t*) q+1, contents, k))
3601                         return -ENXIO;
3602
3603                 *item_size = c->item_size - (1+k);
3604
3605         } else {
3606                 r = message_peek_body(m, &rindex, 1, 1, &q);
3607                 if (r < 0)
3608                         return r;
3609
3610                 l = *(uint8_t*) q;
3611                 r = message_peek_body(m, &rindex, 1, l+1, &q);
3612                 if (r < 0)
3613                         return r;
3614
3615                 if (!validate_signature(q, l))
3616                         return -EBADMSG;
3617
3618                 if (!streq(q, contents))
3619                         return -ENXIO;
3620         }
3621
3622         m->rindex = rindex;
3623
3624         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3625                 c->index++;
3626
3627         return 1;
3628 }
3629
3630 static int build_struct_offsets(
3631                 sd_bus_message *m,
3632                 const char *signature,
3633                 size_t size,
3634                 size_t *item_size,
3635                 size_t **offsets,
3636                 size_t *n_offsets) {
3637
3638         unsigned n_variable = 0, n_total = 0, v;
3639         size_t previous = 0, where;
3640         const char *p;
3641         size_t sz;
3642         void *q;
3643         int r;
3644
3645         assert(m);
3646         assert(item_size);
3647         assert(offsets);
3648         assert(n_offsets);
3649
3650         if (isempty(signature)) {
3651                 *item_size = 0;
3652                 *offsets = NULL;
3653                 *n_offsets = 0;
3654                 return 0;
3655         }
3656
3657         sz = determine_word_size(size, 0);
3658         if (sz <= 0)
3659                 return -EBADMSG;
3660
3661         /* First, loop over signature and count variable elements and
3662          * elements in general. We use this to know how large the
3663          * offset array is at the end of the structure. Note that
3664          * GVariant only stores offsets for all variable size elements
3665          * that are not the last item. */
3666
3667         p = signature;
3668         while (*p != 0) {
3669                 size_t n;
3670
3671                 r = signature_element_length(p, &n);
3672                 if (r < 0)
3673                         return r;
3674                 else {
3675                         char t[n+1];
3676
3677                         memcpy(t, p, n);
3678                         t[n] = 0;
3679
3680                         r = bus_gvariant_is_fixed_size(t);
3681                 }
3682
3683                 if (r < 0)
3684                         return r;
3685                 if (r == 0 && p[n] != 0) /* except the last item */
3686                         n_variable ++;
3687                 n_total++;
3688
3689                 p += n;
3690         }
3691
3692         if (size < n_variable * sz)
3693                 return -EBADMSG;
3694
3695         where = m->rindex + size - (n_variable * sz);
3696         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3697         if (r < 0)
3698                 return r;
3699
3700         v = n_variable;
3701
3702         *offsets = new(size_t, n_total);
3703         if (!*offsets)
3704                 return -ENOMEM;
3705
3706         *n_offsets = 0;
3707
3708         /* Second, loop again and build an offset table */
3709         p = signature;
3710         while (*p != 0) {
3711                 size_t n, offset;
3712                 int k;
3713
3714                 r = signature_element_length(p, &n);
3715                 if (r < 0)
3716                         return r;
3717                 else {
3718                         char t[n+1];
3719
3720                         memcpy(t, p, n);
3721                         t[n] = 0;
3722
3723                         k = bus_gvariant_get_size(t);
3724                         if (k < 0) {
3725                                 size_t x;
3726
3727                                 /* variable size */
3728                                 if (v > 0) {
3729                                         v--;
3730
3731                                         x = read_word_le((uint8_t*) q + v*sz, sz);
3732                                         if (x >= size)
3733                                                 return -EBADMSG;
3734                                         if (m->rindex + x < previous)
3735                                                 return -EBADMSG;
3736                                 } else
3737                                         /* The last item's end
3738                                          * is determined from
3739                                          * the start of the
3740                                          * offset array */
3741                                         x = size - (n_variable * sz);
3742
3743                                 offset = m->rindex + x;
3744
3745                         } else {
3746                                 size_t align;
3747
3748                                 /* fixed size */
3749                                 align = bus_gvariant_get_alignment(t);
3750                                 assert(align > 0);
3751
3752                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3753                         }
3754                 }
3755
3756                 previous = (*offsets)[(*n_offsets)++] = offset;
3757                 p += n;
3758         }
3759
3760         assert(v == 0);
3761         assert(*n_offsets == n_total);
3762
3763         *item_size = (*offsets)[0] - m->rindex;
3764         return 0;
3765 }
3766
3767 static int enter_struct_or_dict_entry(
3768                 sd_bus_message *m,
3769                 struct bus_container *c,
3770                 const char *contents,
3771                 size_t *item_size,
3772                 size_t **offsets,
3773                 size_t *n_offsets) {
3774
3775         int r;
3776
3777         assert(m);
3778         assert(c);
3779         assert(contents);
3780         assert(item_size);
3781         assert(offsets);
3782         assert(n_offsets);
3783
3784         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3785
3786                 /* dbus1 */
3787                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3788                 if (r < 0)
3789                         return r;
3790
3791         } else if (c->item_size <= 0) {
3792
3793                 /* gvariant empty struct */
3794                 *item_size = 0;
3795                 *offsets = NULL;
3796                 *n_offsets = 0;
3797         } else
3798                 /* gvariant with contents */
3799                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3800
3801         return 0;
3802 }
3803
3804 static int bus_message_enter_struct(
3805                 sd_bus_message *m,
3806                 struct bus_container *c,
3807                 const char *contents,
3808                 size_t *item_size,
3809                 size_t **offsets,
3810                 size_t *n_offsets) {
3811
3812         size_t l;
3813         int r;
3814
3815         assert(m);
3816         assert(c);
3817         assert(contents);
3818         assert(item_size);
3819         assert(offsets);
3820         assert(n_offsets);
3821
3822         if (!signature_is_valid(contents, false))
3823                 return -EINVAL;
3824
3825         if (!c->signature || c->signature[c->index] == 0)
3826                 return -ENXIO;
3827
3828         l = strlen(contents);
3829
3830         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3831             !startswith(c->signature + c->index + 1, contents) ||
3832             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3833                 return -ENXIO;
3834
3835         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3836         if (r < 0)
3837                 return r;
3838
3839         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3840                 c->index += 1 + l + 1;
3841
3842         return 1;
3843 }
3844
3845 static int bus_message_enter_dict_entry(
3846                 sd_bus_message *m,
3847                 struct bus_container *c,
3848                 const char *contents,
3849                 size_t *item_size,
3850                 size_t **offsets,
3851                 size_t *n_offsets) {
3852
3853         size_t l;
3854         int r;
3855
3856         assert(m);
3857         assert(c);
3858         assert(contents);
3859
3860         if (!signature_is_pair(contents))
3861                 return -EINVAL;
3862
3863         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3864                 return -ENXIO;
3865
3866         if (!c->signature || c->signature[c->index] == 0)
3867                 return 0;
3868
3869         l = strlen(contents);
3870
3871         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3872             !startswith(c->signature + c->index + 1, contents) ||
3873             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3874                 return -ENXIO;
3875
3876         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3877         if (r < 0)
3878                 return r;
3879
3880         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3881                 c->index += 1 + l + 1;
3882
3883         return 1;
3884 }
3885
3886 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3887                                             char type,
3888                                             const char *contents) {
3889         struct bus_container *c, *w;
3890         uint32_t *array_size = NULL;
3891         char *signature;
3892         size_t before;
3893         size_t *offsets = NULL;
3894         size_t n_offsets = 0, item_size = 0;
3895         int r;
3896
3897         assert_return(m, -EINVAL);
3898         assert_return(m->sealed, -EPERM);
3899         assert_return(type != 0 || !contents, -EINVAL);
3900
3901         if (type == 0 || !contents) {
3902                 const char *cc;
3903                 char tt;
3904
3905                 /* Allow entering into anonymous containers */
3906                 r = sd_bus_message_peek_type(m, &tt, &cc);
3907                 if (r < 0)
3908                         return r;
3909
3910                 if (type != 0 && type != tt)
3911                         return -ENXIO;
3912
3913                 if (contents && !streq(contents, cc))
3914                         return -ENXIO;
3915
3916                 type = tt;
3917                 contents = cc;
3918         }
3919
3920         /*
3921          * We enforce a global limit on container depth, that is much
3922          * higher than the 32 structs and 32 arrays the specification
3923          * mandates. This is simpler to implement for us, and we need
3924          * this only to ensure our container array doesn't grow
3925          * without bounds. We are happy to return any data from a
3926          * message as long as the data itself is valid, even if the
3927          * overall message might be not.
3928          *
3929          * Note that the message signature is validated when
3930          * parsing the headers, and that validation does check the
3931          * 32/32 limit.
3932          *
3933          * Note that the specification defines no limits on the depth
3934          * of stacked variants, but we do.
3935          */
3936         if (m->n_containers >= BUS_CONTAINER_DEPTH)
3937                 return -EBADMSG;
3938
3939         if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
3940                 return -ENOMEM;
3941
3942         if (message_end_of_signature(m))
3943                 return -ENXIO;
3944
3945         if (message_end_of_array(m, m->rindex))
3946                 return 0;
3947
3948         c = message_get_container(m);
3949
3950         signature = strdup(contents);
3951         if (!signature)
3952                 return -ENOMEM;
3953
3954         c->saved_index = c->index;
3955         before = m->rindex;
3956
3957         if (type == SD_BUS_TYPE_ARRAY)
3958                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3959         else if (type == SD_BUS_TYPE_VARIANT)
3960                 r = bus_message_enter_variant(m, c, contents, &item_size);
3961         else if (type == SD_BUS_TYPE_STRUCT)
3962                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3963         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3964                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3965         else
3966                 r = -EINVAL;
3967
3968         if (r <= 0) {
3969                 free(signature);
3970                 free(offsets);
3971                 return r;
3972         }
3973
3974         /* OK, let's fill it in */
3975         w = m->containers + m->n_containers++;
3976         w->enclosing = type;
3977         w->signature = signature;
3978         w->peeked_signature = NULL;
3979         w->index = 0;
3980
3981         w->before = before;
3982         w->begin = m->rindex;
3983         w->end = m->rindex + c->item_size;
3984
3985         w->array_size = array_size;
3986         w->item_size = item_size;
3987         w->offsets = offsets;
3988         w->n_offsets = n_offsets;
3989         w->offset_index = 0;
3990
3991         return 1;
3992 }
3993
3994 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3995         struct bus_container *c;
3996         unsigned saved;
3997         int r;
3998
3999         assert_return(m, -EINVAL);
4000         assert_return(m->sealed, -EPERM);
4001         assert_return(m->n_containers > 0, -ENXIO);
4002
4003         c = message_get_container(m);
4004
4005         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
4006                 if (c->signature && c->signature[c->index] != 0)
4007                         return -EBUSY;
4008         }
4009
4010         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4011                 if (m->rindex < c->end)
4012                         return -EBUSY;
4013
4014         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
4015                 uint32_t l;
4016
4017                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4018                 if (c->begin + l != m->rindex)
4019                         return -EBUSY;
4020         }
4021
4022         free(c->signature);
4023         free(c->peeked_signature);
4024         free(c->offsets);
4025         m->n_containers--;
4026
4027         c = message_get_container(m);
4028
4029         saved = c->index;
4030         c->index = c->saved_index;
4031         r = container_next_item(m, c, &m->rindex);
4032         c->index = saved;
4033         if (r < 0)
4034                 return r;
4035
4036         return 1;
4037 }
4038
4039 static void message_quit_container(sd_bus_message *m) {
4040         struct bus_container *c;
4041
4042         assert(m);
4043         assert(m->sealed);
4044         assert(m->n_containers > 0);
4045
4046         c = message_get_container(m);
4047
4048         /* Undo seeks */
4049         assert(m->rindex >= c->before);
4050         m->rindex = c->before;
4051
4052         /* Free container */
4053         free(c->signature);
4054         free(c->offsets);
4055         m->n_containers--;
4056
4057         /* Correct index of new top-level container */
4058         c = message_get_container(m);
4059         c->index = c->saved_index;
4060 }
4061
4062 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4063         struct bus_container *c;
4064         int r;
4065
4066         assert_return(m, -EINVAL);
4067         assert_return(m->sealed, -EPERM);
4068
4069         if (message_end_of_signature(m))
4070                 goto eof;
4071
4072         if (message_end_of_array(m, m->rindex))
4073                 goto eof;
4074
4075         c = message_get_container(m);
4076
4077         if (bus_type_is_basic(c->signature[c->index])) {
4078                 if (contents)
4079                         *contents = NULL;
4080                 if (type)
4081                         *type = c->signature[c->index];
4082                 return 1;
4083         }
4084
4085         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4086
4087                 if (contents) {
4088                         size_t l;
4089                         char *sig;
4090
4091                         r = signature_element_length(c->signature+c->index+1, &l);
4092                         if (r < 0)
4093                                 return r;
4094
4095                         assert(l >= 1);
4096
4097                         sig = strndup(c->signature + c->index + 1, l);
4098                         if (!sig)
4099                                 return -ENOMEM;
4100
4101                         free(c->peeked_signature);
4102                         *contents = c->peeked_signature = sig;
4103                 }
4104
4105                 if (type)
4106                         *type = SD_BUS_TYPE_ARRAY;
4107
4108                 return 1;
4109         }
4110
4111         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4112             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4113
4114                 if (contents) {
4115                         size_t l;
4116                         char *sig;
4117
4118                         r = signature_element_length(c->signature+c->index, &l);
4119                         if (r < 0)
4120                                 return r;
4121
4122                         assert(l >= 2);
4123                         sig = strndup(c->signature + c->index + 1, l - 2);
4124                         if (!sig)
4125                                 return -ENOMEM;
4126
4127                         free(c->peeked_signature);
4128                         *contents = c->peeked_signature = sig;
4129                 }
4130
4131                 if (type)
4132                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4133
4134                 return 1;
4135         }
4136
4137         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4138                 if (contents) {
4139                         void *q;
4140
4141                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4142                                 size_t k;
4143
4144                                 if (c->item_size < 2)
4145                                         return -EBADMSG;
4146
4147                                 /* Look for the NUL delimiter that
4148                                    separates the payload from the
4149                                    signature. Since the body might be
4150                                    in a different part that then the
4151                                    signature we map byte by byte. */
4152
4153                                 for (k = 2; k <= c->item_size; k++) {
4154                                         size_t where;
4155
4156                                         where = m->rindex + c->item_size - k;
4157                                         r = message_peek_body(m, &where, 1, k, &q);
4158                                         if (r < 0)
4159                                                 return r;
4160
4161                                         if (*(char*) q == 0)
4162                                                 break;
4163                                 }
4164
4165                                 if (k > c->item_size)
4166                                         return -EBADMSG;
4167
4168                                 free(c->peeked_signature);
4169                                 c->peeked_signature = strndup((char*) q + 1, k - 1);
4170                                 if (!c->peeked_signature)
4171                                         return -ENOMEM;
4172
4173                                 if (!signature_is_valid(c->peeked_signature, true))
4174                                         return -EBADMSG;
4175
4176                                 *contents = c->peeked_signature;
4177                         } else {
4178                                 size_t rindex, l;
4179
4180                                 rindex = m->rindex;
4181                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4182                                 if (r < 0)
4183                                         return r;
4184
4185                                 l = *(uint8_t*) q;
4186                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4187                                 if (r < 0)
4188                                         return r;
4189
4190                                 if (!validate_signature(q, l))
4191                                         return -EBADMSG;
4192
4193                                 *contents = q;
4194                         }
4195                 }
4196
4197                 if (type)
4198                         *type = SD_BUS_TYPE_VARIANT;
4199
4200                 return 1;
4201         }
4202
4203         return -EINVAL;
4204
4205 eof:
4206         if (type)
4207                 *type = 0;
4208         if (contents)
4209                 *contents = NULL;
4210         return 0;
4211 }
4212
4213 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4214         struct bus_container *c;
4215
4216         assert_return(m, -EINVAL);
4217         assert_return(m->sealed, -EPERM);
4218
4219         if (complete) {
4220                 message_reset_containers(m);
4221                 m->rindex = 0;
4222
4223                 c = message_get_container(m);
4224         } else {
4225                 c = message_get_container(m);
4226
4227                 c->offset_index = 0;
4228                 c->index = 0;
4229                 m->rindex = c->begin;
4230         }
4231
4232         c->offset_index = 0;
4233         c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4234
4235         return !isempty(c->signature);
4236 }
4237
4238 static int message_read_ap(
4239                 sd_bus_message *m,
4240                 const char *types,
4241                 va_list ap) {
4242
4243         unsigned n_array, n_struct;
4244         TypeStack stack[BUS_CONTAINER_DEPTH];
4245         unsigned stack_ptr = 0;
4246         unsigned n_loop = 0;
4247         int r;
4248
4249         assert(m);
4250
4251         if (isempty(types))
4252                 return 0;
4253
4254         /* Ideally, we'd just call ourselves recursively on every
4255          * complex type. However, the state of a va_list that is
4256          * passed to a function is undefined after that function
4257          * returns. This means we need to docode the va_list linearly
4258          * in a single stackframe. We hence implement our own
4259          * home-grown stack in an array. */
4260
4261         n_array = (unsigned) -1; /* length of current array entries */
4262         n_struct = strlen(types); /* length of current struct contents signature */
4263
4264         for (;;) {
4265                 const char *t;
4266
4267                 n_loop++;
4268
4269                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4270                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4271                         if (r < 0)
4272                                 return r;
4273                         if (r == 0)
4274                                 break;
4275
4276                         r = sd_bus_message_exit_container(m);
4277                         if (r < 0)
4278                                 return r;
4279
4280                         continue;
4281                 }
4282
4283                 t = types;
4284                 if (n_array != (unsigned) -1)
4285                         n_array --;
4286                 else {
4287                         types ++;
4288                         n_struct--;
4289                 }
4290
4291                 switch (*t) {
4292
4293                 case SD_BUS_TYPE_BYTE:
4294                 case SD_BUS_TYPE_BOOLEAN:
4295                 case SD_BUS_TYPE_INT16:
4296                 case SD_BUS_TYPE_UINT16:
4297                 case SD_BUS_TYPE_INT32:
4298                 case SD_BUS_TYPE_UINT32:
4299                 case SD_BUS_TYPE_INT64:
4300                 case SD_BUS_TYPE_UINT64:
4301                 case SD_BUS_TYPE_DOUBLE:
4302                 case SD_BUS_TYPE_STRING:
4303                 case SD_BUS_TYPE_OBJECT_PATH:
4304                 case SD_BUS_TYPE_SIGNATURE:
4305                 case SD_BUS_TYPE_UNIX_FD: {
4306                         void *p;
4307
4308                         p = va_arg(ap, void*);
4309                         r = sd_bus_message_read_basic(m, *t, p);
4310                         if (r < 0)
4311                                 return r;
4312                         if (r == 0) {
4313                                 if (n_loop <= 1)
4314                                         return 0;
4315
4316                                 return -ENXIO;
4317                         }
4318
4319                         break;
4320                 }
4321
4322                 case SD_BUS_TYPE_ARRAY: {
4323                         size_t k;
4324
4325                         r = signature_element_length(t + 1, &k);
4326                         if (r < 0)
4327                                 return r;
4328
4329                         {
4330                                 char s[k + 1];
4331                                 memcpy(s, t + 1, k);
4332                                 s[k] = 0;
4333
4334                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4335                                 if (r < 0)
4336                                         return r;
4337                                 if (r == 0) {
4338                                         if (n_loop <= 1)
4339                                                 return 0;
4340
4341                                         return -ENXIO;
4342                                 }
4343                         }
4344
4345                         if (n_array == (unsigned) -1) {
4346                                 types += k;
4347                                 n_struct -= k;
4348                         }
4349
4350                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4351                         if (r < 0)
4352                                 return r;
4353
4354                         types = t + 1;
4355                         n_struct = k;
4356                         n_array = va_arg(ap, unsigned);
4357
4358                         break;
4359                 }
4360
4361                 case SD_BUS_TYPE_VARIANT: {
4362                         const char *s;
4363
4364                         s = va_arg(ap, const char *);
4365                         if (!s)
4366                                 return -EINVAL;
4367
4368                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4369                         if (r < 0)
4370                                 return r;
4371                         if (r == 0) {
4372                                 if (n_loop <= 1)
4373                                         return 0;
4374
4375                                 return -ENXIO;
4376                         }
4377
4378                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4379                         if (r < 0)
4380                                 return r;
4381
4382                         types = s;
4383                         n_struct = strlen(s);
4384                         n_array = (unsigned) -1;
4385
4386                         break;
4387                 }
4388
4389                 case SD_BUS_TYPE_STRUCT_BEGIN:
4390                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4391                         size_t k;
4392
4393                         r = signature_element_length(t, &k);
4394                         if (r < 0)
4395                                 return r;
4396
4397                         {
4398                                 char s[k - 1];
4399                                 memcpy(s, t + 1, k - 2);
4400                                 s[k - 2] = 0;
4401
4402                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4403                                 if (r < 0)
4404                                         return r;
4405                                 if (r == 0) {
4406                                         if (n_loop <= 1)
4407                                                 return 0;
4408                                         return -ENXIO;
4409                                 }
4410                         }
4411
4412                         if (n_array == (unsigned) -1) {
4413                                 types += k - 1;
4414                                 n_struct -= k - 1;
4415                         }
4416
4417                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4418                         if (r < 0)
4419                                 return r;
4420
4421                         types = t + 1;
4422                         n_struct = k - 2;
4423                         n_array = (unsigned) -1;
4424
4425                         break;
4426                 }
4427
4428                 default:
4429                         return -EINVAL;
4430                 }
4431         }
4432
4433         return 1;
4434 }
4435
4436 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4437         va_list ap;
4438         int r;
4439
4440         assert_return(m, -EINVAL);
4441         assert_return(m->sealed, -EPERM);
4442         assert_return(types, -EINVAL);
4443
4444         va_start(ap, types);
4445         r = message_read_ap(m, types, ap);
4446         va_end(ap);
4447
4448         return r;
4449 }
4450
4451 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4452         int r;
4453
4454         assert_return(m, -EINVAL);
4455         assert_return(m->sealed, -EPERM);
4456
4457         /* If types is NULL, read exactly one element */
4458         if (!types) {
4459                 struct bus_container *c;
4460                 size_t l;
4461
4462                 if (message_end_of_signature(m))
4463                         return -ENXIO;
4464
4465                 if (message_end_of_array(m, m->rindex))
4466                         return 0;
4467
4468                 c = message_get_container(m);
4469
4470                 r = signature_element_length(c->signature + c->index, &l);
4471                 if (r < 0)
4472                         return r;
4473
4474                 types = strndupa(c->signature + c->index, l);
4475         }
4476
4477         switch (*types) {
4478
4479         case 0: /* Nothing to drop */
4480                 return 0;
4481
4482         case SD_BUS_TYPE_BYTE:
4483         case SD_BUS_TYPE_BOOLEAN:
4484         case SD_BUS_TYPE_INT16:
4485         case SD_BUS_TYPE_UINT16:
4486         case SD_BUS_TYPE_INT32:
4487         case SD_BUS_TYPE_UINT32:
4488         case SD_BUS_TYPE_INT64:
4489         case SD_BUS_TYPE_UINT64:
4490         case SD_BUS_TYPE_DOUBLE:
4491         case SD_BUS_TYPE_STRING:
4492         case SD_BUS_TYPE_OBJECT_PATH:
4493         case SD_BUS_TYPE_SIGNATURE:
4494         case SD_BUS_TYPE_UNIX_FD:
4495
4496                 r = sd_bus_message_read_basic(m, *types, NULL);
4497                 if (r <= 0)
4498                         return r;
4499
4500                 r = sd_bus_message_skip(m, types + 1);
4501                 if (r < 0)
4502                         return r;
4503
4504                 return 1;
4505
4506         case SD_BUS_TYPE_ARRAY: {
4507                 size_t k;
4508
4509                 r = signature_element_length(types + 1, &k);
4510                 if (r < 0)
4511                         return r;
4512
4513                 {
4514                         char s[k+1];
4515                         memcpy(s, types+1, k);
4516                         s[k] = 0;
4517
4518                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4519                         if (r <= 0)
4520                                 return r;
4521
4522                         for (;;) {
4523                                 r = sd_bus_message_skip(m, s);
4524                                 if (r < 0)
4525                                         return r;
4526                                 if (r == 0)
4527                                         break;
4528                         }
4529
4530                         r = sd_bus_message_exit_container(m);
4531                         if (r < 0)
4532                                 return r;
4533                 }
4534
4535                 r = sd_bus_message_skip(m, types + 1 + k);
4536                 if (r < 0)
4537                         return r;
4538
4539                 return 1;
4540         }
4541
4542         case SD_BUS_TYPE_VARIANT: {
4543                 const char *contents;
4544                 char x;
4545
4546                 r = sd_bus_message_peek_type(m, &x, &contents);
4547                 if (r <= 0)
4548                         return r;
4549
4550                 if (x != SD_BUS_TYPE_VARIANT)
4551                         return -ENXIO;
4552
4553                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4554                 if (r <= 0)
4555                         return r;
4556
4557                 r = sd_bus_message_skip(m, contents);
4558                 if (r < 0)
4559                         return r;
4560                 assert(r != 0);
4561
4562                 r = sd_bus_message_exit_container(m);
4563                 if (r < 0)
4564                         return r;
4565
4566                 r = sd_bus_message_skip(m, types + 1);
4567                 if (r < 0)
4568                         return r;
4569
4570                 return 1;
4571         }
4572
4573         case SD_BUS_TYPE_STRUCT_BEGIN:
4574         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4575                 size_t k;
4576
4577                 r = signature_element_length(types, &k);
4578                 if (r < 0)
4579                         return r;
4580
4581                 {
4582                         char s[k-1];
4583                         memcpy(s, types+1, k-2);
4584                         s[k-2] = 0;
4585
4586                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4587                         if (r <= 0)
4588                                 return r;
4589
4590                         r = sd_bus_message_skip(m, s);
4591                         if (r < 0)
4592                                 return r;
4593                         assert(r != 0);
4594
4595                         r = sd_bus_message_exit_container(m);
4596                         if (r < 0)
4597                                 return r;
4598                 }
4599
4600                 r = sd_bus_message_skip(m, types + k);
4601                 if (r < 0)
4602                         return r;
4603
4604                 return 1;
4605         }
4606
4607         default:
4608                 return -EINVAL;
4609         }
4610 }
4611
4612 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4613                                        char type,
4614                                        const void **ptr,
4615                                        size_t *size) {
4616         struct bus_container *c;
4617         void *p;
4618         size_t sz;
4619         ssize_t align;
4620         int r;
4621
4622         assert_return(m, -EINVAL);
4623         assert_return(m->sealed, -EPERM);
4624         assert_return(bus_type_is_trivial(type), -EINVAL);
4625         assert_return(ptr, -EINVAL);
4626         assert_return(size, -EINVAL);
4627         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4628
4629         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4630         if (r <= 0)
4631                 return r;
4632
4633         c = message_get_container(m);
4634
4635         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4636                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4637                 if (align < 0)
4638                         return align;
4639
4640                 sz = c->end - c->begin;
4641         } else {
4642                 align = bus_type_get_alignment(type);
4643                 if (align < 0)
4644                         return align;
4645
4646                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4647         }
4648
4649         if (sz == 0)
4650                 /* Zero length array, let's return some aligned
4651                  * pointer that is not NULL */
4652                 p = (uint8_t*) NULL + align;
4653         else {
4654                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4655                 if (r < 0)
4656                         goto fail;
4657         }
4658
4659         r = sd_bus_message_exit_container(m);
4660         if (r < 0)
4661                 goto fail;
4662
4663         *ptr = (const void*) p;
4664         *size = sz;
4665
4666         return 1;
4667
4668 fail:
4669         message_quit_container(m);
4670         return r;
4671 }
4672
4673 static int message_peek_fields(
4674                 sd_bus_message *m,
4675                 size_t *rindex,
4676                 size_t align,
4677                 size_t nbytes,
4678                 void **ret) {
4679
4680         assert(m);
4681         assert(rindex);
4682         assert(align > 0);
4683
4684         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4685 }
4686
4687 static int message_peek_field_uint32(
4688                 sd_bus_message *m,
4689                 size_t *ri,
4690                 size_t item_size,
4691                 uint32_t *ret) {
4692
4693         int r;
4694         void *q;
4695
4696         assert(m);
4697         assert(ri);
4698
4699         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4700                 return -EBADMSG;
4701
4702         /* identical for gvariant and dbus1 */
4703
4704         r = message_peek_fields(m, ri, 4, 4, &q);
4705         if (r < 0)
4706                 return r;
4707
4708         if (ret)
4709                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4710
4711         return 0;
4712 }
4713
4714 static int message_peek_field_string(
4715                 sd_bus_message *m,
4716                 bool (*validate)(const char *p),
4717                 size_t *ri,
4718                 size_t item_size,
4719                 const char **ret) {
4720
4721         uint32_t l;
4722         int r;
4723         void *q;
4724
4725         assert(m);
4726         assert(ri);
4727
4728         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4729
4730                 if (item_size <= 0)
4731                         return -EBADMSG;
4732
4733                 r = message_peek_fields(m, ri, 1, item_size, &q);
4734                 if (r < 0)
4735                         return r;
4736
4737                 l = item_size - 1;
4738         } else {
4739                 r = message_peek_field_uint32(m, ri, 4, &l);
4740                 if (r < 0)
4741                         return r;
4742
4743                 r = message_peek_fields(m, ri, 1, l+1, &q);
4744                 if (r < 0)
4745                         return r;
4746         }
4747
4748         if (validate) {
4749                 if (!validate_nul(q, l))
4750                         return -EBADMSG;
4751
4752                 if (!validate(q))
4753                         return -EBADMSG;
4754         } else {
4755                 if (!validate_string(q, l))
4756                         return -EBADMSG;
4757         }
4758
4759         if (ret)
4760                 *ret = q;
4761
4762         return 0;
4763 }
4764
4765 static int message_peek_field_signature(
4766                 sd_bus_message *m,
4767                 size_t *ri,
4768                 size_t item_size,
4769                 const char **ret) {
4770
4771         size_t l;
4772         int r;
4773         void *q;
4774
4775         assert(m);
4776         assert(ri);
4777
4778         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4779
4780                 if (item_size <= 0)
4781                         return -EBADMSG;
4782
4783                 r = message_peek_fields(m, ri, 1, item_size, &q);
4784                 if (r < 0)
4785                         return r;
4786
4787                 l = item_size - 1;
4788         } else {
4789                 r = message_peek_fields(m, ri, 1, 1, &q);
4790                 if (r < 0)
4791                         return r;
4792
4793                 l = *(uint8_t*) q;
4794                 r = message_peek_fields(m, ri, 1, l+1, &q);
4795                 if (r < 0)
4796                         return r;
4797         }
4798
4799         if (!validate_signature(q, l))
4800                 return -EBADMSG;
4801
4802         if (ret)
4803                 *ret = q;
4804
4805         return 0;
4806 }
4807
4808 static int message_skip_fields(
4809                 sd_bus_message *m,
4810                 size_t *ri,
4811                 uint32_t array_size,
4812                 const char **signature) {
4813
4814         size_t original_index;
4815         int r;
4816
4817         assert(m);
4818         assert(ri);
4819         assert(signature);
4820         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4821
4822         original_index = *ri;
4823
4824         for (;;) {
4825                 char t;
4826                 size_t l;
4827
4828                 if (array_size != (uint32_t) -1 &&
4829                     array_size <= *ri - original_index)
4830                         return 0;
4831
4832                 t = **signature;
4833                 if (!t)
4834                         return 0;
4835
4836                 if (t == SD_BUS_TYPE_STRING) {
4837
4838                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4839                         if (r < 0)
4840                                 return r;
4841
4842                         (*signature)++;
4843
4844                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4845
4846                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4847                         if (r < 0)
4848                                 return r;
4849
4850                         (*signature)++;
4851
4852                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4853
4854                         r = message_peek_field_signature(m, ri, 0, NULL);
4855                         if (r < 0)
4856                                 return r;
4857
4858                         (*signature)++;
4859
4860                 } else if (bus_type_is_basic(t)) {
4861                         ssize_t align, k;
4862
4863                         align = bus_type_get_alignment(t);
4864                         k = bus_type_get_size(t);
4865                         assert(align > 0 && k > 0);
4866
4867                         r = message_peek_fields(m, ri, align, k, NULL);
4868                         if (r < 0)
4869                                 return r;
4870
4871                         (*signature)++;
4872
4873                 } else if (t == SD_BUS_TYPE_ARRAY) {
4874
4875                         r = signature_element_length(*signature+1, &l);
4876                         if (r < 0)
4877                                 return r;
4878
4879                         assert(l >= 1);
4880                         {
4881                                 char sig[l-1], *s;
4882                                 uint32_t nas;
4883                                 int alignment;
4884
4885                                 strncpy(sig, *signature + 1, l-1);
4886                                 s = sig;
4887
4888                                 alignment = bus_type_get_alignment(sig[0]);
4889                                 if (alignment < 0)
4890                                         return alignment;
4891
4892                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4893                                 if (r < 0)
4894                                         return r;
4895                                 if (nas > BUS_ARRAY_MAX_SIZE)
4896                                         return -EBADMSG;
4897
4898                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4899                                 if (r < 0)
4900                                         return r;
4901
4902                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4903                                 if (r < 0)
4904                                         return r;
4905                         }
4906
4907                         (*signature) += 1 + l;
4908
4909                 } else if (t == SD_BUS_TYPE_VARIANT) {
4910                         const char *s;
4911
4912                         r = message_peek_field_signature(m, ri, 0, &s);
4913                         if (r < 0)
4914                                 return r;
4915
4916                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4917                         if (r < 0)
4918                                 return r;
4919
4920                         (*signature)++;
4921
4922                 } else if (t == SD_BUS_TYPE_STRUCT ||
4923                            t == SD_BUS_TYPE_DICT_ENTRY) {
4924
4925                         r = signature_element_length(*signature, &l);
4926                         if (r < 0)
4927                                 return r;
4928
4929                         assert(l >= 2);
4930                         {
4931                                 char sig[l-1], *s;
4932                                 strncpy(sig, *signature + 1, l-1);
4933                                 s = sig;
4934
4935                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4936                                 if (r < 0)
4937                                         return r;
4938                         }
4939
4940                         *signature += l;
4941                 } else
4942                         return -EINVAL;
4943         }
4944 }
4945
4946 int bus_message_parse_fields(sd_bus_message *m) {
4947         size_t ri;
4948         int r;
4949         uint32_t unix_fds = 0;
4950         bool unix_fds_set = false;
4951         void *offsets = NULL;
4952         unsigned n_offsets = 0;
4953         size_t sz = 0;
4954         unsigned i = 0;
4955
4956         assert(m);
4957
4958         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4959                 void *q;
4960
4961                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4962                 if (sz > 0) {
4963                         size_t framing;
4964
4965                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4966                         r = message_peek_fields(m, &ri, 1, sz, &q);
4967                         if (r < 0)
4968                                 return r;
4969
4970                         framing = read_word_le(q, sz);
4971                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4972                                 return -EBADMSG;
4973                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4974                                 return -EBADMSG;
4975
4976                         ri = framing;
4977                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4978                         if (r < 0)
4979                                 return r;
4980
4981                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4982                 }
4983         }
4984
4985         ri = 0;
4986         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4987                 _cleanup_free_ char *sig = NULL;
4988                 const char *signature;
4989                 uint8_t *header;
4990                 size_t item_size = (size_t) -1;
4991
4992                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4993                         if (i >= n_offsets)
4994                                 break;
4995
4996                         if (i == 0)
4997                                 ri = 0;
4998                         else
4999                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
5000                 }
5001
5002                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
5003                 if (r < 0)
5004                         return r;
5005
5006                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5007                         size_t where, end;
5008                         char *b;
5009                         void *q;
5010
5011                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
5012
5013                         if (end < ri)
5014                                 return -EBADMSG;
5015
5016                         where = ri = ALIGN_TO(ri, 8);
5017                         item_size = end - ri;
5018                         r = message_peek_fields(m, &where, 1, item_size, &q);
5019                         if (r < 0)
5020                                 return r;
5021
5022                         b = memrchr(q, 0, item_size);
5023                         if (!b)
5024                                 return -EBADMSG;
5025
5026                         sig = strndup(b+1, item_size - (b+1-(char*) q));
5027                         if (!sig)
5028                                 return -ENOMEM;
5029
5030                         signature = sig;
5031                         item_size = b - (char*) q;
5032                 } else {
5033                         r = message_peek_field_signature(m, &ri, 0, &signature);
5034                         if (r < 0)
5035                                 return r;
5036                 }
5037
5038                 switch (*header) {
5039                 case _BUS_MESSAGE_HEADER_INVALID:
5040                         return -EBADMSG;
5041
5042                 case BUS_MESSAGE_HEADER_PATH:
5043
5044                         if (m->path)
5045                                 return -EBADMSG;
5046
5047                         if (!streq(signature, "o"))
5048                                 return -EBADMSG;
5049
5050                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5051                         break;
5052
5053                 case BUS_MESSAGE_HEADER_INTERFACE:
5054
5055                         if (m->interface)
5056                                 return -EBADMSG;
5057
5058                         if (!streq(signature, "s"))
5059                                 return -EBADMSG;
5060
5061                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5062                         break;
5063
5064                 case BUS_MESSAGE_HEADER_MEMBER:
5065
5066                         if (m->member)
5067                                 return -EBADMSG;
5068
5069                         if (!streq(signature, "s"))
5070                                 return -EBADMSG;
5071
5072                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5073                         break;
5074
5075                 case BUS_MESSAGE_HEADER_ERROR_NAME:
5076
5077                         if (m->error.name)
5078                                 return -EBADMSG;
5079
5080                         if (!streq(signature, "s"))
5081                                 return -EBADMSG;
5082
5083                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5084                         if (r >= 0)
5085                                 m->error._need_free = -1;
5086
5087                         break;
5088
5089                 case BUS_MESSAGE_HEADER_DESTINATION:
5090
5091                         if (m->destination)
5092                                 return -EBADMSG;
5093
5094                         if (!streq(signature, "s"))
5095                                 return -EBADMSG;
5096
5097                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5098                         break;
5099
5100                 case BUS_MESSAGE_HEADER_SENDER:
5101
5102                         if (m->sender)
5103                                 return -EBADMSG;
5104
5105                         if (!streq(signature, "s"))
5106                                 return -EBADMSG;
5107
5108                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5109
5110                         if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5111                                 m->creds.unique_name = (char*) m->sender;
5112                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5113                         }
5114
5115                         break;
5116
5117
5118                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5119                         const char *s;
5120                         char *c;
5121
5122                         if (m->root_container.signature)
5123                                 return -EBADMSG;
5124
5125                         if (!streq(signature, "g"))
5126                                 return -EBADMSG;
5127
5128                         r = message_peek_field_signature(m, &ri, item_size, &s);
5129                         if (r < 0)
5130                                 return r;
5131
5132                         c = strdup(s);
5133                         if (!c)
5134                                 return -ENOMEM;
5135
5136                         free(m->root_container.signature);
5137                         m->root_container.signature = c;
5138                         break;
5139                 }
5140
5141                 case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
5142                         uint32_t serial;
5143
5144                         if (m->reply_cookie != 0)
5145                                 return -EBADMSG;
5146
5147                         if (!streq(signature, "u"))
5148                                 return -EBADMSG;
5149
5150                         r = message_peek_field_uint32(m, &ri, item_size, &serial);
5151                         if (r < 0)
5152                                 return r;
5153
5154                         m->reply_cookie = serial;
5155
5156                         if (m->reply_cookie == 0)
5157                                 return -EBADMSG;
5158
5159                         break;
5160                 }
5161
5162                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5163                         if (unix_fds_set)
5164                                 return -EBADMSG;
5165
5166                         if (!streq(signature, "u"))
5167                                 return -EBADMSG;
5168
5169                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5170                         if (r < 0)
5171                                 return -EBADMSG;
5172
5173                         unix_fds_set = true;
5174                         break;
5175
5176                 default:
5177                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5178                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5179                 }
5180
5181                 if (r < 0)
5182                         return r;
5183
5184                 i++;
5185         }
5186
5187         if (m->n_fds != unix_fds)
5188                 return -EBADMSG;
5189
5190         switch (m->header->type) {
5191
5192         case SD_BUS_MESSAGE_SIGNAL:
5193                 if (!m->path || !m->interface || !m->member)
5194                         return -EBADMSG;
5195
5196                 if (m->reply_cookie != 0)
5197                         return -EBADMSG;
5198
5199                 break;
5200
5201         case SD_BUS_MESSAGE_METHOD_CALL:
5202
5203                 if (!m->path || !m->member)
5204                         return -EBADMSG;
5205
5206                 if (m->reply_cookie != 0)
5207                         return -EBADMSG;
5208
5209                 break;
5210
5211         case SD_BUS_MESSAGE_METHOD_RETURN:
5212
5213                 if (m->reply_cookie == 0)
5214                         return -EBADMSG;
5215                 break;
5216
5217         case SD_BUS_MESSAGE_METHOD_ERROR:
5218
5219                 if (m->reply_cookie == 0 || !m->error.name)
5220                         return -EBADMSG;
5221                 break;
5222         }
5223
5224         /* Refuse non-local messages that claim they are local */
5225         if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5226                 return -EBADMSG;
5227         if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5228                 return -EBADMSG;
5229         if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5230                 return -EBADMSG;
5231
5232         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5233
5234         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5235                 r = build_struct_offsets(
5236                                 m,
5237                                 m->root_container.signature,
5238                                 BUS_MESSAGE_BODY_SIZE(m),
5239                                 &m->root_container.item_size,
5240                                 &m->root_container.offsets,
5241                                 &m->root_container.n_offsets);
5242                 if (r < 0)
5243                         return r;
5244         }
5245
5246         /* Try to read the error message, but if we can't it's a non-issue */
5247         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5248                 sd_bus_message_read(m, "s", &m->error.message);
5249
5250         return 0;
5251 }
5252
5253 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5254         assert_return(m, -EINVAL);
5255         assert_return(destination, -EINVAL);
5256         assert_return(!m->sealed, -EPERM);
5257         assert_return(!m->destination, -EEXIST);
5258
5259         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5260 }
5261
5262 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5263         size_t total;
5264         void *p, *e;
5265         unsigned i;
5266         struct bus_body_part *part;
5267
5268         assert(m);
5269         assert(buffer);
5270         assert(sz);
5271
5272         total = BUS_MESSAGE_SIZE(m);
5273
5274         p = malloc(total);
5275         if (!p)
5276                 return -ENOMEM;
5277
5278         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5279         MESSAGE_FOREACH_PART(part, i, m)
5280                 e = mempcpy(e, part->data, part->size);
5281
5282         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5283
5284         *buffer = p;
5285         *sz = total;
5286
5287         return 0;
5288 }
5289
5290 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5291         int r;
5292
5293         assert(m);
5294         assert(l);
5295
5296         r = sd_bus_message_enter_container(m, 'a', "s");
5297         if (r <= 0)
5298                 return r;
5299
5300         for (;;) {
5301                 const char *s;
5302
5303                 r = sd_bus_message_read_basic(m, 's', &s);
5304                 if (r < 0)
5305                         return r;
5306                 if (r == 0)
5307                         break;
5308
5309                 r = strv_extend(l, s);
5310                 if (r < 0)
5311                         return r;
5312         }
5313
5314         r = sd_bus_message_exit_container(m);
5315         if (r < 0)
5316                 return r;
5317
5318         return 1;
5319 }
5320
5321 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5322         char **strv = NULL;
5323         int r;
5324
5325         assert_return(m, -EINVAL);
5326         assert_return(m->sealed, -EPERM);
5327         assert_return(l, -EINVAL);
5328
5329         r = bus_message_read_strv_extend(m, &strv);
5330         if (r <= 0) {
5331                 strv_free(strv);
5332                 return r;
5333         }
5334
5335         *l = strv;
5336         return 1;
5337 }
5338
5339 int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) {
5340         const char *contents;
5341         unsigned j;
5342         char type;
5343         int r;
5344
5345         assert(m);
5346         assert(str);
5347         assert(strv);
5348
5349         r = sd_bus_message_rewind(m, true);
5350         if (r < 0)
5351                 return r;
5352
5353         for (j = 0;; j++) {
5354                 r = sd_bus_message_peek_type(m, &type, &contents);
5355                 if (r < 0)
5356                         return r;
5357                 if (r == 0)
5358                         return -ENXIO;
5359
5360                 /* Don't match against arguments after the first one we don't understand */
5361                 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE) &&
5362                     !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
5363                         return -ENXIO;
5364
5365                 if (j >= i)
5366                         break;
5367
5368                 r = sd_bus_message_skip(m, NULL);
5369                 if (r < 0)
5370                         return r;
5371         }
5372
5373         if (type == SD_BUS_TYPE_ARRAY) {
5374
5375                 r = sd_bus_message_read_strv(m, strv);
5376                 if (r < 0)
5377                         return r;
5378
5379                 *str = NULL;
5380
5381         } else {
5382                 r = sd_bus_message_read_basic(m, type, str);
5383                 if (r < 0)
5384                         return r;
5385
5386                 *strv = NULL;
5387         }
5388
5389         return 0;
5390 }
5391
5392 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5393         size_t full;
5394
5395         assert(h);
5396         assert(size);
5397
5398         if (size < sizeof(struct bus_header))
5399                 return false;
5400
5401         full = sizeof(struct bus_header) +
5402                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5403
5404         return size >= full;
5405 }
5406
5407 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5408         size_t fs, bs;
5409
5410         assert(h);
5411         assert(sum);
5412
5413         if (h->endian == BUS_NATIVE_ENDIAN) {
5414                 fs = h->fields_size;
5415                 bs = h->body_size;
5416         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5417                 fs = bswap_32(h->fields_size);
5418                 bs = bswap_32(h->body_size);
5419         } else
5420                 return -EBADMSG;
5421
5422         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5423         return 0;
5424 }
5425
5426 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5427         assert_return(m, EINVAL);
5428
5429         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5430                 return 0;
5431
5432         return sd_bus_error_get_errno(&m->error);
5433 }
5434
5435 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5436         struct bus_container *c;
5437
5438         assert_return(m, NULL);
5439
5440         c = complete ? &m->root_container : message_get_container(m);
5441         return strempty(c->signature);
5442 }
5443
5444 _public_ int sd_bus_message_is_empty(sd_bus_message *m) {
5445         assert_return(m, -EINVAL);
5446
5447         return isempty(m->root_container.signature);
5448 }
5449
5450 _public_ int sd_bus_message_has_signature(sd_bus_message *m, const char *signature) {
5451         assert_return(m, -EINVAL);
5452
5453         return streq(strempty(m->root_container.signature), strempty(signature));
5454 }
5455
5456 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5457         bool done_something = false;
5458         int r;
5459
5460         assert_return(m, -EINVAL);
5461         assert_return(source, -EINVAL);
5462         assert_return(!m->sealed, -EPERM);
5463         assert_return(source->sealed, -EPERM);
5464
5465         do {
5466                 const char *contents;
5467                 char type;
5468                 union {
5469                         uint8_t u8;
5470                         uint16_t u16;
5471                         int16_t s16;
5472                         uint32_t u32;
5473                         int32_t s32;
5474                         uint64_t u64;
5475                         int64_t s64;
5476                         double d64;
5477                         const char *string;
5478                         int i;
5479                 } basic;
5480
5481                 r = sd_bus_message_peek_type(source, &type, &contents);
5482                 if (r < 0)
5483                         return r;
5484                 if (r == 0)
5485                         break;
5486
5487                 done_something = true;
5488
5489                 if (bus_type_is_container(type) > 0) {
5490
5491                         r = sd_bus_message_enter_container(source, type, contents);
5492                         if (r < 0)
5493                                 return r;
5494
5495                         r = sd_bus_message_open_container(m, type, contents);
5496                         if (r < 0)
5497                                 return r;
5498
5499                         r = sd_bus_message_copy(m, source, true);
5500                         if (r < 0)
5501                                 return r;
5502
5503                         r = sd_bus_message_close_container(m);
5504                         if (r < 0)
5505                                 return r;
5506
5507                         r = sd_bus_message_exit_container(source);
5508                         if (r < 0)
5509                                 return r;
5510
5511                         continue;
5512                 }
5513
5514                 r = sd_bus_message_read_basic(source, type, &basic);
5515                 if (r < 0)
5516                         return r;
5517
5518                 assert(r > 0);
5519
5520                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5521                     type == SD_BUS_TYPE_SIGNATURE ||
5522                     type == SD_BUS_TYPE_STRING)
5523                         r = sd_bus_message_append_basic(m, type, basic.string);
5524                 else
5525                         r = sd_bus_message_append_basic(m, type, &basic);
5526
5527                 if (r < 0)
5528                         return r;
5529
5530         } while (all);
5531
5532         return done_something;
5533 }
5534
5535 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5536         const char *c;
5537         char t;
5538         int r;
5539
5540         assert_return(m, -EINVAL);
5541         assert_return(m->sealed, -EPERM);
5542         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5543         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5544         assert_return(type || contents, -EINVAL);
5545         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5546
5547         r = sd_bus_message_peek_type(m, &t, &c);
5548         if (r <= 0)
5549                 return r;
5550
5551         if (type != 0 && type != t)
5552                 return 0;
5553
5554         if (contents && !streq_ptr(contents, c))
5555                 return 0;
5556
5557         return 1;
5558 }
5559
5560 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5561         assert_return(m, NULL);
5562
5563         return m->bus;
5564 }
5565
5566 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5567         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
5568         usec_t timeout;
5569         int r;
5570
5571         assert(bus);
5572         assert(m);
5573         assert(*m);
5574
5575         switch ((*m)->header->type) {
5576
5577         case SD_BUS_MESSAGE_SIGNAL:
5578                 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5579                 if (r < 0)
5580                         return r;
5581
5582                 break;
5583
5584         case SD_BUS_MESSAGE_METHOD_CALL:
5585                 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5586                 if (r < 0)
5587                         return r;
5588
5589                 break;
5590
5591         case SD_BUS_MESSAGE_METHOD_RETURN:
5592         case SD_BUS_MESSAGE_METHOD_ERROR:
5593
5594                 n = message_new(bus, (*m)->header->type);
5595                 if (!n)
5596                         return -ENOMEM;
5597
5598                 n->reply_cookie = (*m)->reply_cookie;
5599                 r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
5600                 if (r < 0)
5601                         return r;
5602
5603                 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5604                         r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5605                         if (r < 0)
5606                                 return r;
5607
5608                         n->error._need_free = -1;
5609                 }
5610
5611                 break;
5612
5613         default:
5614                 return -EINVAL;
5615         }
5616
5617         if ((*m)->destination && !n->destination) {
5618                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5619                 if (r < 0)
5620                         return r;
5621         }
5622
5623         if ((*m)->sender && !n->sender) {
5624                 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5625                 if (r < 0)
5626                         return r;
5627         }
5628
5629         n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5630
5631         r = sd_bus_message_copy(n, *m, true);
5632         if (r < 0)
5633                 return r;
5634
5635         timeout = (*m)->timeout;
5636         if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5637                 timeout = BUS_DEFAULT_TIMEOUT;
5638
5639         r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5640         if (r < 0)
5641                 return r;
5642
5643         sd_bus_message_unref(*m);
5644         *m = n;
5645         n = NULL;
5646
5647         return 0;
5648 }
5649
5650 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5651         assert(m);
5652         assert(sender);
5653
5654         assert_return(!m->sealed, -EPERM);
5655         assert_return(!m->sender, -EPERM);
5656
5657         return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5658 }
5659
5660 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5661         assert_return(m, -EINVAL);
5662         assert_return(priority, -EINVAL);
5663
5664         *priority = m->priority;
5665         return 0;
5666 }
5667
5668 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5669         assert_return(m, -EINVAL);
5670         assert_return(!m->sealed, -EPERM);
5671
5672         m->priority = priority;
5673         return 0;
5674 }