chiark / gitweb /
811374422717ff0cdbab7b5c3d52ceea88b63f6c
[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 = 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 = 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(signature);
3558         assert(item_size);
3559         assert(offsets);
3560         assert(n_offsets);
3561
3562         sz = determine_word_size(size, 0);
3563
3564         /* First, loop over signature and count variable elements and
3565          * elements in general. We use this to know how large the
3566          * offset array is at the end of the structure. Note that
3567          * GVariant only stores offsets for all variable size elements
3568          * that are not the last item. */
3569
3570         p = signature;
3571         while (*p != 0) {
3572                 size_t n;
3573
3574                 r = signature_element_length(p, &n);
3575                 if (r < 0)
3576                         return r;
3577                 else {
3578                         char t[n+1];
3579
3580                         memcpy(t, p, n);
3581                         t[n] = 0;
3582
3583                         r = bus_gvariant_is_fixed_size(t);
3584                 }
3585
3586                 if (r < 0)
3587                         return r;
3588                 if (r == 0 && p[n] != 0) /* except the last item */
3589                         n_variable ++;
3590                 n_total++;
3591
3592                 p += n;
3593         }
3594
3595         if (size < n_variable * sz)
3596                 return -EBADMSG;
3597
3598         where = m->rindex + size - (n_variable * sz);
3599         r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3600         if (r < 0)
3601                 return r;
3602
3603         v = n_variable;
3604
3605         *offsets = new(size_t, n_total);
3606         if (!*offsets)
3607                 return -ENOMEM;
3608
3609         *n_offsets = 0;
3610
3611         /* Second, loop again and build an offset table */
3612         p = signature;
3613         while (*p != 0) {
3614                 size_t n, offset;
3615                 int k;
3616
3617                 r = signature_element_length(p, &n);
3618                 if (r < 0)
3619                         return r;
3620                 else {
3621                         char t[n+1];
3622
3623                         memcpy(t, p, n);
3624                         t[n] = 0;
3625
3626                         k = bus_gvariant_get_size(t);
3627                         if (k < 0) {
3628                                 size_t x;
3629
3630                                 /* variable size */
3631                                 if (v > 0) {
3632                                         v--;
3633
3634                                         x = read_word_le((uint8_t*) q + v*sz, sz);
3635                                         if (x >= size)
3636                                                 return -EBADMSG;
3637                                         if (m->rindex + x < previous)
3638                                                 return -EBADMSG;
3639                                 } else
3640                                         /* The last item's end
3641                                          * is determined from
3642                                          * the start of the
3643                                          * offset array */
3644                                         x = size - (n_variable * sz);
3645
3646                                 offset = m->rindex + x;
3647
3648                         } else {
3649                                 size_t align;
3650
3651                                 /* fixed size */
3652                                 align = bus_gvariant_get_alignment(t);
3653                                 assert(align > 0);
3654
3655                                 offset = (*n_offsets == 0 ? m->rindex  : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3656                         }
3657                 }
3658
3659                 previous = (*offsets)[(*n_offsets)++] = offset;
3660                 p += n;
3661         }
3662
3663         assert(v == 0);
3664         assert(*n_offsets == n_total);
3665
3666         *item_size = (*offsets)[0] - m->rindex;
3667         return 0;
3668 }
3669
3670 static int enter_struct_or_dict_entry(
3671                 sd_bus_message *m,
3672                 struct bus_container *c,
3673                 const char *contents,
3674                 size_t *item_size,
3675                 size_t **offsets,
3676                 size_t *n_offsets) {
3677
3678         int r;
3679
3680         assert(m);
3681         assert(c);
3682         assert(contents);
3683         assert(item_size);
3684         assert(offsets);
3685         assert(n_offsets);
3686
3687         if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3688
3689                 /* dbus1 */
3690                 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3691                 if (r < 0)
3692                         return r;
3693
3694         } else if (c->item_size <= 0) {
3695
3696                 /* gvariant empty struct */
3697                 *item_size = 0;
3698                 *offsets = NULL;
3699                 *n_offsets = 0;
3700         } else
3701                 /* gvariant with contents */
3702                 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3703
3704         return 0;
3705 }
3706
3707 static int bus_message_enter_struct(
3708                 sd_bus_message *m,
3709                 struct bus_container *c,
3710                 const char *contents,
3711                 size_t *item_size,
3712                 size_t **offsets,
3713                 size_t *n_offsets) {
3714
3715         size_t l;
3716         int r;
3717
3718         assert(m);
3719         assert(c);
3720         assert(contents);
3721         assert(item_size);
3722         assert(offsets);
3723         assert(n_offsets);
3724
3725         if (!signature_is_valid(contents, false))
3726                 return -EINVAL;
3727
3728         if (!c->signature || c->signature[c->index] == 0)
3729                 return -ENXIO;
3730
3731         l = strlen(contents);
3732
3733         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3734             !startswith(c->signature + c->index + 1, contents) ||
3735             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
3736                 return -ENXIO;
3737
3738         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3739         if (r < 0)
3740                 return r;
3741
3742         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3743                 c->index += 1 + l + 1;
3744
3745         return 1;
3746 }
3747
3748 static int bus_message_enter_dict_entry(
3749                 sd_bus_message *m,
3750                 struct bus_container *c,
3751                 const char *contents,
3752                 size_t *item_size,
3753                 size_t **offsets,
3754                 size_t *n_offsets) {
3755
3756         size_t l;
3757         int r;
3758
3759         assert(m);
3760         assert(c);
3761         assert(contents);
3762
3763         if (!signature_is_pair(contents))
3764                 return -EINVAL;
3765
3766         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3767                 return -ENXIO;
3768
3769         if (!c->signature || c->signature[c->index] == 0)
3770                 return 0;
3771
3772         l = strlen(contents);
3773
3774         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
3775             !startswith(c->signature + c->index + 1, contents) ||
3776             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
3777                 return -ENXIO;
3778
3779         r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
3780         if (r < 0)
3781                 return r;
3782
3783         if (c->enclosing != SD_BUS_TYPE_ARRAY)
3784                 c->index += 1 + l + 1;
3785
3786         return 1;
3787 }
3788
3789 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
3790                                             char type,
3791                                             const char *contents) {
3792         struct bus_container *c, *w;
3793         uint32_t *array_size = NULL;
3794         char *signature;
3795         size_t before;
3796         size_t *offsets = NULL;
3797         size_t n_offsets = 0, item_size = 0;
3798         int r;
3799
3800         assert_return(m, -EINVAL);
3801         assert_return(m->sealed, -EPERM);
3802         assert_return(type != 0 || !contents, -EINVAL);
3803
3804         if (type == 0 || !contents) {
3805                 const char *cc;
3806                 char tt;
3807
3808                 /* Allow entering into anonymous containers */
3809                 r = sd_bus_message_peek_type(m, &tt, &cc);
3810                 if (r < 0)
3811                         return r;
3812
3813                 if (type != 0 && type != tt)
3814                         return -ENXIO;
3815
3816                 if (contents && !streq(contents, cc))
3817                         return -ENXIO;
3818
3819                 type = tt;
3820                 contents = cc;
3821         }
3822
3823         /*
3824          * We enforce a global limit on container depth, that is much
3825          * higher than the 32 structs and 32 arrays the specification
3826          * mandates. This is simpler to implement for us, and we need
3827          * this only to ensure our container array doesn't grow
3828          * without bounds. We are happy to return any data from a
3829          * message as long as the data itself is valid, even if the
3830          * overall message might be not.
3831          *
3832          * Note that the message signature is validated when
3833          * parsing the headers, and that validation does check the
3834          * 32/32 limit.
3835          *
3836          * Note that the specification defines no limits on the depth
3837          * of stacked variants, but we do.
3838          */
3839         if (m->n_containers >= BUS_CONTAINER_DEPTH)
3840                 return -EBADMSG;
3841
3842         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3843         if (!w)
3844                 return -ENOMEM;
3845         m->containers = w;
3846
3847         if (message_end_of_signature(m))
3848                 return -ENXIO;
3849
3850         if (message_end_of_array(m, m->rindex))
3851                 return 0;
3852
3853         c = message_get_container(m);
3854
3855         signature = strdup(contents);
3856         if (!signature)
3857                 return -ENOMEM;
3858
3859         c->saved_index = c->index;
3860         before = m->rindex;
3861
3862         if (type == SD_BUS_TYPE_ARRAY)
3863                 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
3864         else if (type == SD_BUS_TYPE_VARIANT)
3865                 r = bus_message_enter_variant(m, c, contents, &item_size);
3866         else if (type == SD_BUS_TYPE_STRUCT)
3867                 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
3868         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3869                 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
3870         else
3871                 r = -EINVAL;
3872
3873         if (r <= 0) {
3874                 free(signature);
3875                 free(offsets);
3876                 return r;
3877         }
3878
3879         /* OK, let's fill it in */
3880         w += m->n_containers++;
3881         w->enclosing = type;
3882         w->signature = signature;
3883         w->index = 0;
3884
3885         w->before = before;
3886         w->begin = m->rindex;
3887         w->end = m->rindex + c->item_size;
3888
3889         w->array_size = array_size;
3890         w->item_size = item_size;
3891         w->offsets = offsets;
3892         w->n_offsets = n_offsets;
3893         w->offset_index = 0;
3894
3895         return 1;
3896 }
3897
3898 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
3899         struct bus_container *c;
3900         int r;
3901
3902         assert_return(m, -EINVAL);
3903         assert_return(m->sealed, -EPERM);
3904         assert_return(m->n_containers > 0, -ENXIO);
3905
3906         c = message_get_container(m);
3907
3908         if (c->enclosing != SD_BUS_TYPE_ARRAY) {
3909                 if (c->signature && c->signature[c->index] != 0)
3910                         return -EBUSY;
3911         }
3912
3913         if (BUS_MESSAGE_IS_GVARIANT(m)) {
3914                 if (m->rindex < c->end)
3915                         return -EBUSY;
3916
3917         } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3918                 uint32_t l;
3919
3920                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3921                 if (c->begin + l != m->rindex)
3922                         return -EBUSY;
3923         }
3924
3925         free(c->signature);
3926         free(c->offsets);
3927         m->n_containers--;
3928
3929         c = message_get_container(m);
3930
3931         r = container_next_item(m, c, &m->rindex);
3932         if (r < 0)
3933                 return r;
3934
3935         return 1;
3936 }
3937
3938 static void message_quit_container(sd_bus_message *m) {
3939         struct bus_container *c;
3940
3941         assert(m);
3942         assert(m->sealed);
3943         assert(m->n_containers > 0);
3944
3945         c = message_get_container(m);
3946
3947         /* Undo seeks */
3948         assert(m->rindex >= c->before);
3949         m->rindex = c->before;
3950
3951         /* Free container */
3952         free(c->signature);
3953         free(c->offsets);
3954         m->n_containers--;
3955
3956         /* Correct index of new top-level container */
3957         c = message_get_container(m);
3958         c->index = c->saved_index;
3959 }
3960
3961 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3962         struct bus_container *c;
3963         int r;
3964
3965         assert_return(m, -EINVAL);
3966         assert_return(m->sealed, -EPERM);
3967
3968         if (message_end_of_signature(m))
3969                 goto eof;
3970
3971         if (message_end_of_array(m, m->rindex))
3972                 goto eof;
3973
3974         c = message_get_container(m);
3975
3976         if (bus_type_is_basic(c->signature[c->index])) {
3977                 if (contents)
3978                         *contents = NULL;
3979                 if (type)
3980                         *type = c->signature[c->index];
3981                 return 1;
3982         }
3983
3984         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3985
3986                 if (contents) {
3987                         size_t l;
3988                         char *sig;
3989
3990                         r = signature_element_length(c->signature+c->index+1, &l);
3991                         if (r < 0)
3992                                 return r;
3993
3994                         assert(l >= 1);
3995
3996                         sig = strndup(c->signature + c->index + 1, l);
3997                         if (!sig)
3998                                 return -ENOMEM;
3999
4000                         free(m->peeked_signature);
4001                         m->peeked_signature = sig;
4002
4003                         *contents = sig;
4004                 }
4005
4006                 if (type)
4007                         *type = SD_BUS_TYPE_ARRAY;
4008
4009                 return 1;
4010         }
4011
4012         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4013             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4014
4015                 if (contents) {
4016                         size_t l;
4017                         char *sig;
4018
4019                         r = signature_element_length(c->signature+c->index, &l);
4020                         if (r < 0)
4021                                 return r;
4022
4023                         assert(l >= 2);
4024                         sig = strndup(c->signature + c->index + 1, l - 2);
4025                         if (!sig)
4026                                 return -ENOMEM;
4027
4028                         free(m->peeked_signature);
4029                         m->peeked_signature = sig;
4030
4031                         *contents = sig;
4032                 }
4033
4034                 if (type)
4035                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4036
4037                 return 1;
4038         }
4039
4040         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4041                 if (contents) {
4042                         void *q;
4043
4044                         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4045                                 size_t k;
4046
4047                                 if (c->item_size < 2)
4048                                         return -EBADMSG;
4049
4050                                 /* Look for the NUL delimiter that
4051                                    separates the payload from the
4052                                    signature. Since the body might be
4053                                    in a different part that then the
4054                                    signature we map byte by byte. */
4055
4056                                 for (k = 2; k <= c->item_size; k++) {
4057                                         size_t where;
4058
4059                                         where = m->rindex + c->item_size - k;
4060                                         r = message_peek_body(m, &where, 1, k, &q);
4061                                         if (r < 0)
4062                                                 return r;
4063
4064                                         if (*(char*) q == 0)
4065                                                 break;
4066                                 }
4067
4068                                 if (k > c->item_size)
4069                                         return -EBADMSG;
4070
4071                                 free(m->peeked_signature);
4072                                 m->peeked_signature = strndup((char*) q + 1, k - 1);
4073                                 if (!m->peeked_signature)
4074                                         return -ENOMEM;
4075
4076                                 if (!signature_is_valid(m->peeked_signature, true))
4077                                         return -EBADMSG;
4078
4079                                 *contents = m->peeked_signature;
4080                         } else {
4081                                 size_t rindex, l;
4082
4083                                 rindex = m->rindex;
4084                                 r = message_peek_body(m, &rindex, 1, 1, &q);
4085                                 if (r < 0)
4086                                         return r;
4087
4088                                 l = *(uint8_t*) q;
4089                                 r = message_peek_body(m, &rindex, 1, l+1, &q);
4090                                 if (r < 0)
4091                                         return r;
4092
4093                                 if (!validate_signature(q, l))
4094                                         return -EBADMSG;
4095
4096                                 *contents = q;
4097                         }
4098                 }
4099
4100                 if (type)
4101                         *type = SD_BUS_TYPE_VARIANT;
4102
4103                 return 1;
4104         }
4105
4106         return -EINVAL;
4107
4108 eof:
4109         if (type)
4110                 *type = 0;
4111         if (contents)
4112                 *contents = NULL;
4113         return 0;
4114 }
4115
4116 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4117         struct bus_container *c;
4118
4119         assert_return(m, -EINVAL);
4120         assert_return(m->sealed, -EPERM);
4121
4122         if (complete) {
4123                 message_reset_containers(m);
4124                 m->rindex = 0;
4125
4126                 c = message_get_container(m);
4127         } else {
4128                 c = message_get_container(m);
4129
4130                 c->offset_index = 0;
4131                 c->index = 0;
4132                 m->rindex = c->begin;
4133         }
4134
4135         return !isempty(c->signature);
4136 }
4137
4138 static int message_read_ap(
4139                 sd_bus_message *m,
4140                 const char *types,
4141                 va_list ap) {
4142
4143         unsigned n_array, n_struct;
4144         TypeStack stack[BUS_CONTAINER_DEPTH];
4145         unsigned stack_ptr = 0;
4146         unsigned n_loop = 0;
4147         int r;
4148
4149         assert(m);
4150
4151         if (isempty(types))
4152                 return 0;
4153
4154         /* Ideally, we'd just call ourselves recursively on every
4155          * complex type. However, the state of a va_list that is
4156          * passed to a function is undefined after that function
4157          * returns. This means we need to docode the va_list linearly
4158          * in a single stackframe. We hence implement our own
4159          * home-grown stack in an array. */
4160
4161         n_array = (unsigned) -1; /* lenght of current array entries */
4162         n_struct = strlen(types); /* length of current struct contents signature */
4163
4164         for (;;) {
4165                 const char *t;
4166
4167                 n_loop++;
4168
4169                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4170                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4171                         if (r < 0)
4172                                 return r;
4173                         if (r == 0)
4174                                 break;
4175
4176                         r = sd_bus_message_exit_container(m);
4177                         if (r < 0)
4178                                 return r;
4179
4180                         continue;
4181                 }
4182
4183                 t = types;
4184                 if (n_array != (unsigned) -1)
4185                         n_array --;
4186                 else {
4187                         types ++;
4188                         n_struct--;
4189                 }
4190
4191                 switch (*t) {
4192
4193                 case SD_BUS_TYPE_BYTE:
4194                 case SD_BUS_TYPE_BOOLEAN:
4195                 case SD_BUS_TYPE_INT16:
4196                 case SD_BUS_TYPE_UINT16:
4197                 case SD_BUS_TYPE_INT32:
4198                 case SD_BUS_TYPE_UINT32:
4199                 case SD_BUS_TYPE_INT64:
4200                 case SD_BUS_TYPE_UINT64:
4201                 case SD_BUS_TYPE_DOUBLE:
4202                 case SD_BUS_TYPE_STRING:
4203                 case SD_BUS_TYPE_OBJECT_PATH:
4204                 case SD_BUS_TYPE_SIGNATURE:
4205                 case SD_BUS_TYPE_UNIX_FD: {
4206                         void *p;
4207
4208                         p = va_arg(ap, void*);
4209                         r = sd_bus_message_read_basic(m, *t, p);
4210                         if (r < 0)
4211                                 return r;
4212                         if (r == 0) {
4213                                 if (n_loop <= 1)
4214                                         return 0;
4215
4216                                 return -ENXIO;
4217                         }
4218
4219                         break;
4220                 }
4221
4222                 case SD_BUS_TYPE_ARRAY: {
4223                         size_t k;
4224
4225                         r = signature_element_length(t + 1, &k);
4226                         if (r < 0)
4227                                 return r;
4228
4229                         {
4230                                 char s[k + 1];
4231                                 memcpy(s, t + 1, k);
4232                                 s[k] = 0;
4233
4234                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4235                                 if (r < 0)
4236                                         return r;
4237                                 if (r == 0) {
4238                                         if (n_loop <= 1)
4239                                                 return 0;
4240
4241                                         return -ENXIO;
4242                                 }
4243                         }
4244
4245                         if (n_array == (unsigned) -1) {
4246                                 types += k;
4247                                 n_struct -= k;
4248                         }
4249
4250                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4251                         if (r < 0)
4252                                 return r;
4253
4254                         types = t + 1;
4255                         n_struct = k;
4256                         n_array = va_arg(ap, unsigned);
4257
4258                         break;
4259                 }
4260
4261                 case SD_BUS_TYPE_VARIANT: {
4262                         const char *s;
4263
4264                         s = va_arg(ap, const char *);
4265                         if (!s)
4266                                 return -EINVAL;
4267
4268                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4269                         if (r < 0)
4270                                 return r;
4271                         if (r == 0) {
4272                                 if (n_loop <= 1)
4273                                         return 0;
4274
4275                                 return -ENXIO;
4276                         }
4277
4278                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4279                         if (r < 0)
4280                                 return r;
4281
4282                         types = s;
4283                         n_struct = strlen(s);
4284                         n_array = (unsigned) -1;
4285
4286                         break;
4287                 }
4288
4289                 case SD_BUS_TYPE_STRUCT_BEGIN:
4290                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4291                         size_t k;
4292
4293                         r = signature_element_length(t, &k);
4294                         if (r < 0)
4295                                 return r;
4296
4297                         {
4298                                 char s[k - 1];
4299                                 memcpy(s, t + 1, k - 2);
4300                                 s[k - 2] = 0;
4301
4302                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4303                                 if (r < 0)
4304                                         return r;
4305                                 if (r == 0) {
4306                                         if (n_loop <= 1)
4307                                                 return 0;
4308                                         return -ENXIO;
4309                                 }
4310                         }
4311
4312                         if (n_array == (unsigned) -1) {
4313                                 types += k - 1;
4314                                 n_struct -= k - 1;
4315                         }
4316
4317                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4318                         if (r < 0)
4319                                 return r;
4320
4321                         types = t + 1;
4322                         n_struct = k - 2;
4323                         n_array = (unsigned) -1;
4324
4325                         break;
4326                 }
4327
4328                 default:
4329                         return -EINVAL;
4330                 }
4331         }
4332
4333         return 1;
4334 }
4335
4336 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4337         va_list ap;
4338         int r;
4339
4340         assert_return(m, -EINVAL);
4341         assert_return(m->sealed, -EPERM);
4342         assert_return(types, -EINVAL);
4343
4344         va_start(ap, types);
4345         r = message_read_ap(m, types, ap);
4346         va_end(ap);
4347
4348         return r;
4349 }
4350
4351 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4352         int r;
4353
4354         assert_return(m, -EINVAL);
4355         assert_return(m->sealed, -EPERM);
4356         assert_return(types, -EINVAL);
4357
4358         if (isempty(types))
4359                 return 0;
4360
4361         switch (*types) {
4362
4363         case SD_BUS_TYPE_BYTE:
4364         case SD_BUS_TYPE_BOOLEAN:
4365         case SD_BUS_TYPE_INT16:
4366         case SD_BUS_TYPE_UINT16:
4367         case SD_BUS_TYPE_INT32:
4368         case SD_BUS_TYPE_UINT32:
4369         case SD_BUS_TYPE_INT64:
4370         case SD_BUS_TYPE_UINT64:
4371         case SD_BUS_TYPE_DOUBLE:
4372         case SD_BUS_TYPE_STRING:
4373         case SD_BUS_TYPE_OBJECT_PATH:
4374         case SD_BUS_TYPE_SIGNATURE:
4375         case SD_BUS_TYPE_UNIX_FD:
4376
4377                 r = sd_bus_message_read_basic(m, *types, NULL);
4378                 if (r <= 0)
4379                         return r;
4380
4381                 r = sd_bus_message_skip(m, types + 1);
4382                 if (r < 0)
4383                         return r;
4384
4385                 return 1;
4386
4387         case SD_BUS_TYPE_ARRAY: {
4388                 size_t k;
4389
4390                 r = signature_element_length(types + 1, &k);
4391                 if (r < 0)
4392                         return r;
4393
4394                 {
4395                         char s[k+1];
4396                         memcpy(s, types+1, k);
4397                         s[k] = 0;
4398
4399                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4400                         if (r <= 0)
4401                                 return r;
4402
4403                         for (;;) {
4404                                 r = sd_bus_message_skip(m, s);
4405                                 if (r < 0)
4406                                         return r;
4407                                 if (r == 0)
4408                                         break;
4409                         }
4410
4411                         r = sd_bus_message_exit_container(m);
4412                         if (r < 0)
4413                                 return r;
4414                 }
4415
4416                 r = sd_bus_message_skip(m, types + 1 + k);
4417                 if (r < 0)
4418                         return r;
4419
4420                 return 1;
4421         }
4422
4423         case SD_BUS_TYPE_VARIANT: {
4424                 const char *contents;
4425                 char x;
4426
4427                 r = sd_bus_message_peek_type(m, &x, &contents);
4428                 if (r <= 0)
4429                         return r;
4430
4431                 if (x != SD_BUS_TYPE_VARIANT)
4432                         return -ENXIO;
4433
4434                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4435                 if (r <= 0)
4436                         return r;
4437
4438                 r = sd_bus_message_skip(m, contents);
4439                 if (r < 0)
4440                         return r;
4441                 assert(r != 0);
4442
4443                 r = sd_bus_message_exit_container(m);
4444                 if (r < 0)
4445                         return r;
4446
4447                 r = sd_bus_message_skip(m, types + 1);
4448                 if (r < 0)
4449                         return r;
4450
4451                 return 1;
4452         }
4453
4454         case SD_BUS_TYPE_STRUCT_BEGIN:
4455         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4456                 size_t k;
4457
4458                 r = signature_element_length(types, &k);
4459                 if (r < 0)
4460                         return r;
4461
4462                 {
4463                         char s[k-1];
4464                         memcpy(s, types+1, k-2);
4465                         s[k-2] = 0;
4466
4467                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4468                         if (r <= 0)
4469                                 return r;
4470
4471                         r = sd_bus_message_skip(m, s);
4472                         if (r < 0)
4473                                 return r;
4474                         assert(r != 0);
4475
4476                         r = sd_bus_message_exit_container(m);
4477                         if (r < 0)
4478                                 return r;
4479                 }
4480
4481                 r = sd_bus_message_skip(m, types + k);
4482                 if (r < 0)
4483                         return r;
4484
4485                 return 1;
4486         }
4487
4488         default:
4489                 return -EINVAL;
4490         }
4491 }
4492
4493 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4494                                        char type,
4495                                        const void **ptr,
4496                                        size_t *size) {
4497         struct bus_container *c;
4498         void *p;
4499         size_t sz;
4500         ssize_t align;
4501         int r;
4502
4503         assert_return(m, -EINVAL);
4504         assert_return(m->sealed, -EPERM);
4505         assert_return(bus_type_is_trivial(type), -EINVAL);
4506         assert_return(ptr, -EINVAL);
4507         assert_return(size, -EINVAL);
4508         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4509
4510         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4511         if (r <= 0)
4512                 return r;
4513
4514         c = message_get_container(m);
4515
4516         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4517                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4518                 if (align < 0)
4519                         return align;
4520
4521                 sz = c->end - c->begin;
4522         } else {
4523                 align = bus_type_get_alignment(type);
4524                 if (align < 0)
4525                         return align;
4526
4527                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4528         }
4529
4530         if (sz == 0)
4531                 /* Zero length array, let's return some aligned
4532                  * pointer that is not NULL */
4533                 p = (uint8_t*) NULL + align;
4534         else {
4535                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4536                 if (r < 0)
4537                         goto fail;
4538         }
4539
4540         r = sd_bus_message_exit_container(m);
4541         if (r < 0)
4542                 goto fail;
4543
4544         *ptr = (const void*) p;
4545         *size = sz;
4546
4547         return 1;
4548
4549 fail:
4550         message_quit_container(m);
4551         return r;
4552 }
4553
4554 static int message_peek_fields(
4555                 sd_bus_message *m,
4556                 size_t *rindex,
4557                 size_t align,
4558                 size_t nbytes,
4559                 void **ret) {
4560
4561         assert(m);
4562         assert(rindex);
4563         assert(align > 0);
4564
4565         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4566 }
4567
4568 static int message_peek_field_uint32(
4569                 sd_bus_message *m,
4570                 size_t *ri,
4571                 size_t item_size,
4572                 uint32_t *ret) {
4573
4574         int r;
4575         void *q;
4576
4577         assert(m);
4578         assert(ri);
4579
4580         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4581                 return -EBADMSG;
4582
4583         /* identical for gvariant and dbus1 */
4584
4585         r = message_peek_fields(m, ri, 4, 4, &q);
4586         if (r < 0)
4587                 return r;
4588
4589         if (ret)
4590                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4591
4592         return 0;
4593 }
4594
4595 static int message_peek_field_string(
4596                 sd_bus_message *m,
4597                 bool (*validate)(const char *p),
4598                 size_t *ri,
4599                 size_t item_size,
4600                 const char **ret) {
4601
4602         uint32_t l;
4603         int r;
4604         void *q;
4605
4606         assert(m);
4607         assert(ri);
4608
4609         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4610
4611                 if (item_size <= 0)
4612                         return -EBADMSG;
4613
4614                 r = message_peek_fields(m, ri, 1, item_size, &q);
4615                 if (r < 0)
4616                         return r;
4617
4618                 l = item_size - 1;
4619         } else {
4620                 r = message_peek_field_uint32(m, ri, 4, &l);
4621                 if (r < 0)
4622                         return r;
4623
4624                 r = message_peek_fields(m, ri, 1, l+1, &q);
4625                 if (r < 0)
4626                         return r;
4627         }
4628
4629         if (validate) {
4630                 if (!validate_nul(q, l))
4631                         return -EBADMSG;
4632
4633                 if (!validate(q))
4634                         return -EBADMSG;
4635         } else {
4636                 if (!validate_string(q, l))
4637                         return -EBADMSG;
4638         }
4639
4640         if (ret)
4641                 *ret = q;
4642
4643         return 0;
4644 }
4645
4646 static int message_peek_field_signature(
4647                 sd_bus_message *m,
4648                 size_t *ri,
4649                 size_t item_size,
4650                 const char **ret) {
4651
4652         size_t l;
4653         int r;
4654         void *q;
4655
4656         assert(m);
4657         assert(ri);
4658
4659         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4660
4661                 if (item_size <= 0)
4662                         return -EBADMSG;
4663
4664                 r = message_peek_fields(m, ri, 1, item_size, &q);
4665                 if (r < 0)
4666                         return r;
4667
4668                 l = item_size - 1;
4669         } else {
4670                 r = message_peek_fields(m, ri, 1, 1, &q);
4671                 if (r < 0)
4672                         return r;
4673
4674                 l = *(uint8_t*) q;
4675                 r = message_peek_fields(m, ri, 1, l+1, &q);
4676                 if (r < 0)
4677                         return r;
4678         }
4679
4680         if (!validate_signature(q, l))
4681                 return -EBADMSG;
4682
4683         if (ret)
4684                 *ret = q;
4685
4686         return 0;
4687 }
4688
4689 static int message_skip_fields(
4690                 sd_bus_message *m,
4691                 size_t *ri,
4692                 uint32_t array_size,
4693                 const char **signature) {
4694
4695         size_t original_index;
4696         int r;
4697
4698         assert(m);
4699         assert(ri);
4700         assert(signature);
4701         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4702
4703         original_index = *ri;
4704
4705         for (;;) {
4706                 char t;
4707                 size_t l;
4708
4709                 if (array_size != (uint32_t) -1 &&
4710                     array_size <= *ri - original_index)
4711                         return 0;
4712
4713                 t = **signature;
4714                 if (!t)
4715                         return 0;
4716
4717                 if (t == SD_BUS_TYPE_STRING) {
4718
4719                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4720                         if (r < 0)
4721                                 return r;
4722
4723                         (*signature)++;
4724
4725                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4726
4727                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4728                         if (r < 0)
4729                                 return r;
4730
4731                         (*signature)++;
4732
4733                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4734
4735                         r = message_peek_field_signature(m, ri, 0, NULL);
4736                         if (r < 0)
4737                                 return r;
4738
4739                         (*signature)++;
4740
4741                 } else if (bus_type_is_basic(t)) {
4742                         ssize_t align, k;
4743
4744                         align = bus_type_get_alignment(t);
4745                         k = bus_type_get_size(t);
4746                         assert(align > 0 && k > 0);
4747
4748                         r = message_peek_fields(m, ri, align, k, NULL);
4749                         if (r < 0)
4750                                 return r;
4751
4752                         (*signature)++;
4753
4754                 } else if (t == SD_BUS_TYPE_ARRAY) {
4755
4756                         r = signature_element_length(*signature+1, &l);
4757                         if (r < 0)
4758                                 return r;
4759
4760                         assert(l >= 1);
4761                         {
4762                                 char sig[l-1], *s;
4763                                 uint32_t nas;
4764                                 int alignment;
4765
4766                                 strncpy(sig, *signature + 1, l-1);
4767                                 s = sig;
4768
4769                                 alignment = bus_type_get_alignment(sig[0]);
4770                                 if (alignment < 0)
4771                                         return alignment;
4772
4773                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4774                                 if (r < 0)
4775                                         return r;
4776                                 if (nas > BUS_ARRAY_MAX_SIZE)
4777                                         return -EBADMSG;
4778
4779                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4780                                 if (r < 0)
4781                                         return r;
4782
4783                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4784                                 if (r < 0)
4785                                         return r;
4786                         }
4787
4788                         (*signature) += 1 + l;
4789
4790                 } else if (t == SD_BUS_TYPE_VARIANT) {
4791                         const char *s;
4792
4793                         r = message_peek_field_signature(m, ri, 0, &s);
4794                         if (r < 0)
4795                                 return r;
4796
4797                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4798                         if (r < 0)
4799                                 return r;
4800
4801                         (*signature)++;
4802
4803                 } else if (t == SD_BUS_TYPE_STRUCT ||
4804                            t == SD_BUS_TYPE_DICT_ENTRY) {
4805
4806                         r = signature_element_length(*signature, &l);
4807                         if (r < 0)
4808                                 return r;
4809
4810                         assert(l >= 2);
4811                         {
4812                                 char sig[l-1], *s;
4813                                 strncpy(sig, *signature + 1, l-1);
4814                                 s = sig;
4815
4816                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4817                                 if (r < 0)
4818                                         return r;
4819                         }
4820
4821                         *signature += l;
4822                 } else
4823                         return -EINVAL;
4824         }
4825 }
4826
4827 int bus_message_parse_fields(sd_bus_message *m) {
4828         size_t ri;
4829         int r;
4830         uint32_t unix_fds = 0;
4831         void *offsets = NULL;
4832         unsigned n_offsets = 0;
4833         size_t sz;
4834         unsigned i = 0;
4835
4836         assert(m);
4837
4838         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4839                 void *q;
4840
4841                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4842                 if (sz > 0) {
4843                         size_t framing;
4844
4845                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4846                         r = message_peek_fields(m, &ri, 1, sz, &q);
4847                         if (r < 0)
4848                                 return r;
4849
4850                         framing = read_word_le(q, sz);
4851                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4852                                 return -EBADMSG;
4853                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4854                                 return -EBADMSG;
4855
4856                         ri = framing;
4857                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4858                         if (r < 0)
4859                                 return r;
4860
4861                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4862                 }
4863         }
4864
4865         ri = 0;
4866         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4867                 _cleanup_free_ char *sig = NULL;
4868                 const char *signature;
4869                 uint8_t *header;
4870                 size_t item_size = (size_t) -1;
4871
4872                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4873                         if (i >= n_offsets)
4874                                 break;
4875
4876                         if (i == 0)
4877                                 ri = 0;
4878                         else
4879                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4880                 }
4881
4882                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4883                 if (r < 0)
4884                         return r;
4885
4886                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4887                         size_t where, end;
4888                         char *b;
4889                         void *q;
4890
4891                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
4892
4893                         if (end < ri)
4894                                 return -EBADMSG;
4895
4896                         where = ri = ALIGN_TO(ri, 8);
4897                         item_size = end - ri;
4898                         r = message_peek_fields(m, &where, 1, item_size, &q);
4899                         if (r < 0)
4900                                 return r;
4901
4902                         b = memrchr(q, 0, item_size);
4903                         if (!b)
4904                                 return -EBADMSG;
4905
4906                         sig = strndup(b+1, item_size - (b+1-(char*) q));
4907                         if (!sig)
4908                                 return -ENOMEM;
4909
4910                         signature = sig;
4911                         item_size = b - (char*) q;
4912                 } else {
4913                         r = message_peek_field_signature(m, &ri, 0, &signature);
4914                         if (r < 0)
4915                                 return r;
4916                 }
4917
4918                 switch (*header) {
4919                 case _BUS_MESSAGE_HEADER_INVALID:
4920                         return -EBADMSG;
4921
4922                 case BUS_MESSAGE_HEADER_PATH:
4923
4924                         if (m->path)
4925                                 return -EBADMSG;
4926
4927                         if (!streq(signature, "o"))
4928                                 return -EBADMSG;
4929
4930                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4931                         break;
4932
4933                 case BUS_MESSAGE_HEADER_INTERFACE:
4934
4935                         if (m->interface)
4936                                 return -EBADMSG;
4937
4938                         if (!streq(signature, "s"))
4939                                 return -EBADMSG;
4940
4941                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4942                         break;
4943
4944                 case BUS_MESSAGE_HEADER_MEMBER:
4945
4946                         if (m->member)
4947                                 return -EBADMSG;
4948
4949                         if (!streq(signature, "s"))
4950                                 return -EBADMSG;
4951
4952                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4953                         break;
4954
4955                 case BUS_MESSAGE_HEADER_ERROR_NAME:
4956
4957                         if (m->error.name)
4958                                 return -EBADMSG;
4959
4960                         if (!streq(signature, "s"))
4961                                 return -EBADMSG;
4962
4963                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
4964                         if (r >= 0)
4965                                 m->error._need_free = -1;
4966
4967                         break;
4968
4969                 case BUS_MESSAGE_HEADER_DESTINATION:
4970
4971                         if (m->destination)
4972                                 return -EBADMSG;
4973
4974                         if (!streq(signature, "s"))
4975                                 return -EBADMSG;
4976
4977                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
4978                         break;
4979
4980                 case BUS_MESSAGE_HEADER_SENDER:
4981
4982                         if (m->sender)
4983                                 return -EBADMSG;
4984
4985                         if (!streq(signature, "s"))
4986                                 return -EBADMSG;
4987
4988                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
4989
4990                         if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
4991                                 m->creds.unique_name = (char*) m->sender;
4992                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
4993                         }
4994
4995                         break;
4996
4997
4998                 case BUS_MESSAGE_HEADER_SIGNATURE: {
4999                         const char *s;
5000                         char *c;
5001
5002                         if (m->root_container.signature)
5003                                 return -EBADMSG;
5004
5005                         if (!streq(signature, "g"))
5006                                 return -EBADMSG;
5007
5008                         r = message_peek_field_signature(m, &ri, item_size, &s);
5009                         if (r < 0)
5010                                 return r;
5011
5012                         c = strdup(s);
5013                         if (!c)
5014                                 return -ENOMEM;
5015
5016                         free(m->root_container.signature);
5017                         m->root_container.signature = c;
5018                         break;
5019                 }
5020
5021                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5022                         if (m->reply_serial != 0)
5023                                 return -EBADMSG;
5024
5025                         if (!streq(signature, "u"))
5026                                 return -EBADMSG;
5027
5028                         r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5029                         if (r < 0)
5030                                 return r;
5031
5032                         if (m->reply_serial == 0)
5033                                 return -EBADMSG;
5034
5035                         break;
5036
5037                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5038                         if (unix_fds != 0)
5039                                 return -EBADMSG;
5040
5041                         if (!streq(signature, "u"))
5042                                 return -EBADMSG;
5043
5044                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5045                         if (r < 0)
5046                                 return -EBADMSG;
5047
5048                         if (unix_fds == 0)
5049                                 return -EBADMSG;
5050
5051                         break;
5052
5053                 default:
5054                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5055                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5056                 }
5057
5058                 if (r < 0)
5059                         return r;
5060
5061                 i++;
5062         }
5063
5064         if (m->n_fds != unix_fds)
5065                 return -EBADMSG;
5066
5067         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
5068                 return -EBADMSG;
5069
5070         switch (m->header->type) {
5071
5072         case SD_BUS_MESSAGE_SIGNAL:
5073                 if (!m->path || !m->interface || !m->member)
5074                         return -EBADMSG;
5075                 break;
5076
5077         case SD_BUS_MESSAGE_METHOD_CALL:
5078
5079                 if (!m->path || !m->member)
5080                         return -EBADMSG;
5081
5082                 break;
5083
5084         case SD_BUS_MESSAGE_METHOD_RETURN:
5085
5086                 if (m->reply_serial == 0)
5087                         return -EBADMSG;
5088                 break;
5089
5090         case SD_BUS_MESSAGE_METHOD_ERROR:
5091
5092                 if (m->reply_serial == 0 || !m->error.name)
5093                         return -EBADMSG;
5094                 break;
5095         }
5096
5097         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5098
5099         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5100                 r = build_struct_offsets(
5101                                 m,
5102                                 m->root_container.signature,
5103                                 BUS_MESSAGE_BODY_SIZE(m),
5104                                 &m->root_container.item_size,
5105                                 &m->root_container.offsets,
5106                                 &m->root_container.n_offsets);
5107                 if (r < 0)
5108                         return r;
5109         }
5110
5111         /* Try to read the error message, but if we can't it's a non-issue */
5112         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5113                 sd_bus_message_read(m, "s", &m->error.message);
5114
5115         return 0;
5116 }
5117
5118 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5119         assert_return(m, -EINVAL);
5120         assert_return(destination, -EINVAL);
5121         assert_return(!m->sealed, -EPERM);
5122         assert_return(!m->destination, -EEXIST);
5123
5124         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5125 }
5126
5127 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5128         size_t total;
5129         void *p, *e;
5130         unsigned i;
5131         struct bus_body_part *part;
5132
5133         assert(m);
5134         assert(buffer);
5135         assert(sz);
5136
5137         total = BUS_MESSAGE_SIZE(m);
5138
5139         p = malloc(total);
5140         if (!p)
5141                 return -ENOMEM;
5142
5143         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5144         MESSAGE_FOREACH_PART(part, i, m)
5145                 e = mempcpy(e, part->data, part->size);
5146
5147         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5148
5149         *buffer = p;
5150         *sz = total;
5151
5152         return 0;
5153 }
5154
5155 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5156         int r;
5157
5158         assert(m);
5159         assert(l);
5160
5161         r = sd_bus_message_enter_container(m, 'a', "s");
5162         if (r <= 0)
5163                 return r;
5164
5165         for (;;) {
5166                 const char *s;
5167
5168                 r = sd_bus_message_read_basic(m, 's', &s);
5169                 if (r < 0)
5170                         return r;
5171                 if (r == 0)
5172                         break;
5173
5174                 r = strv_extend(l, s);
5175                 if (r < 0)
5176                         return r;
5177         }
5178
5179         r = sd_bus_message_exit_container(m);
5180         if (r < 0)
5181                 return r;
5182
5183         return 1;
5184 }
5185
5186 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5187         char **strv = NULL;
5188         int r;
5189
5190         assert_return(m, -EINVAL);
5191         assert_return(m->sealed, -EPERM);
5192         assert_return(l, -EINVAL);
5193
5194         r = bus_message_read_strv_extend(m, &strv);
5195         if (r <= 0) {
5196                 strv_free(strv);
5197                 return r;
5198         }
5199
5200         *l = strv;
5201         return 1;
5202 }
5203
5204 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5205         int r;
5206         const char *t = NULL;
5207         unsigned j;
5208
5209         assert(m);
5210
5211         r = sd_bus_message_rewind(m, true);
5212         if (r < 0)
5213                 return NULL;
5214
5215         for (j = 0; j <= i; j++) {
5216                 char type;
5217
5218                 r = sd_bus_message_peek_type(m, &type, NULL);
5219                 if (r < 0)
5220                         return NULL;
5221
5222                 if (type != SD_BUS_TYPE_STRING &&
5223                     type != SD_BUS_TYPE_OBJECT_PATH &&
5224                     type != SD_BUS_TYPE_SIGNATURE)
5225                         return NULL;
5226
5227                 r = sd_bus_message_read_basic(m, type, &t);
5228                 if (r < 0)
5229                         return NULL;
5230         }
5231
5232         return t;
5233 }
5234
5235 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5236         size_t full;
5237
5238         assert(h);
5239         assert(size);
5240
5241         if (size < sizeof(struct bus_header))
5242                 return false;
5243
5244         full = sizeof(struct bus_header) +
5245                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5246
5247         return size >= full;
5248 }
5249
5250 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5251         size_t fs, bs;
5252
5253         assert(h);
5254         assert(sum);
5255
5256         if (h->endian == BUS_NATIVE_ENDIAN) {
5257                 fs = h->fields_size;
5258                 bs = h->body_size;
5259         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5260                 fs = bswap_32(h->fields_size);
5261                 bs = bswap_32(h->body_size);
5262         } else
5263                 return -EBADMSG;
5264
5265         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5266         return 0;
5267 }
5268
5269 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5270         assert_return(m, -EINVAL);
5271
5272         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5273                 return 0;
5274
5275         return sd_bus_error_get_errno(&m->error);
5276 }
5277
5278 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5279         struct bus_container *c;
5280
5281         assert_return(m, NULL);
5282
5283         c = complete ? &m->root_container : message_get_container(m);
5284         return c->signature ?: "";
5285 }
5286
5287 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5288         bool done_something = false;
5289         int r;
5290
5291         assert_return(m, -EINVAL);
5292         assert_return(source, -EINVAL);
5293         assert_return(!m->sealed, -EPERM);
5294         assert_return(source->sealed, -EPERM);
5295
5296         do {
5297                 const char *contents;
5298                 char type;
5299                 union {
5300                         uint8_t u8;
5301                         uint16_t u16;
5302                         int16_t s16;
5303                         uint32_t u32;
5304                         int32_t s32;
5305                         uint64_t u64;
5306                         int64_t s64;
5307                         double d64;
5308                         const char *string;
5309                         int i;
5310                 } basic;
5311
5312                 r = sd_bus_message_peek_type(source, &type, &contents);
5313                 if (r < 0)
5314                         return r;
5315                 if (r == 0)
5316                         break;
5317
5318                 done_something = true;
5319
5320                 if (bus_type_is_container(type) > 0) {
5321
5322                         r = sd_bus_message_enter_container(source, type, contents);
5323                         if (r < 0)
5324                                 return r;
5325
5326                         r = sd_bus_message_open_container(m, type, contents);
5327                         if (r < 0)
5328                                 return r;
5329
5330                         r = sd_bus_message_copy(m, source, true);
5331                         if (r < 0)
5332                                 return r;
5333
5334                         r = sd_bus_message_close_container(m);
5335                         if (r < 0)
5336                                 return r;
5337
5338                         r = sd_bus_message_exit_container(source);
5339                         if (r < 0)
5340                                 return r;
5341
5342                         continue;
5343                 }
5344
5345                 r = sd_bus_message_read_basic(source, type, &basic);
5346                 if (r < 0)
5347                         return r;
5348
5349                 assert(r > 0);
5350
5351                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5352                     type == SD_BUS_TYPE_SIGNATURE ||
5353                     type == SD_BUS_TYPE_STRING)
5354                         r = sd_bus_message_append_basic(m, type, basic.string);
5355                 else
5356                         r = sd_bus_message_append_basic(m, type, &basic);
5357
5358                 if (r < 0)
5359                         return r;
5360
5361         } while (all);
5362
5363         return done_something;
5364 }
5365
5366 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5367         const char *c;
5368         char t;
5369         int r;
5370
5371         assert_return(m, -EINVAL);
5372         assert_return(m->sealed, -EPERM);
5373         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5374         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5375         assert_return(type || contents, -EINVAL);
5376         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5377
5378         r = sd_bus_message_peek_type(m, &t, &c);
5379         if (r <= 0)
5380                 return r;
5381
5382         if (type != 0 && type != t)
5383                 return 0;
5384
5385         if (contents && !streq_ptr(contents, c))
5386                 return 0;
5387
5388         return 1;
5389 }
5390
5391 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5392         assert_return(m, NULL);
5393
5394         return m->bus;
5395 }