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