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